Текст
                    Matlab R2007 с нуля4
Книга + Видеокурс


A Guide to Mat lab for beginners and experienced users Brian R. Hunt Ronald L.Lipsman Jonathan M.Rosenberg with Kevin R. Coombes John E. Osborn GarrettJ. Stuck UNIVERSITY OF CAMBRIDGE
Matlab R2007 с нуля®! Книга + Видеокурс Brian R. Hunt Ronald L.Lipsman Jonathan M.Rosenberg with Kevin R. Coombes John E. Osborn GarrettJ. Stuck «ЛУЧШИЕ КНИГИ» Москва
УДК 004:51 ББК22.19с51+32.973.26-018.2 Н92 Hunt, Brian R H92 Matlab R2007 с нуля®! Книга + Видеокурс.: [пер. с англ.] / Brian R. Hunt [и др.]. - М.: Лучшие книги, 2008. - 352 с.: ил. + CD-ROM. (Серия «Книга + Видеокурс»). — Доп. тит. л. англ. — ISBN 978-5-93673095-5. Агентство CIP РГБ Книга, которую Вы держите в руках, представляет собой уникальную и самую современную методику обучения: это одновременно и хорошо иллюстрированная книга, и очень наглядный ВИДЕОКУРС. Прочитав книгу и посмотрев видеокурс, Вы быстро сможете производить математические и технические вычисления любой сложности в программе Matlab. Книга является официальным учебным курсом Кембриджского университета, который успешно используется в учебном процессе на протяжении ряда лет. ВАЖНАЯ ИНФОРМАЦИЯ ДЛЯ ТОВАРОВЕДОВ и ПОКУПАТЕЛЕЙ Обращаем Ваше внимание на то, что данное издание выпускается в двух вариантах. Существует версия настоящего издания без видеокурса: «Matlab. Официальный учебный курс Кембриджского университета» с более низкой ценой. Выбирайте то издание, которое Вам больше подходит. Главный редактор издательства В. Б. Комягин Научный редактор И. В. Сергеев Перевод Д.Н. Проценко, А. А. Мизонов Выпускающий редактор И. Г. Колмыкова Редактор-координатор А. Д. Куксова Дизайн обложки Борис Клюйко Корректор А. Н. Левина Верстка н. К. Теджоева Создание видеокурса Dignatamedia Authorized translation from the English language edition, entitled A Guide to Matlab, 2st Edition, ISBN 0-521-61565-8, by Cambridge University Press (The Edinburgh Building, Cambridge CB2 2RU, UK). Copyright © B.Hunt, R.Lipsman, J.Rosenberg, K.Coombes, J.Osborn, and G.Stuck 2001,2006. This publication is in copyright. Subject to statutory exception and to the provision of relevant collective licensing agreements, no reproduction of any part may take place without the written permission of Cambridge University Press. Russian language edition published by Triumph Publishing (OOO «Издательство Триумф»). Copyright © 2008. Авторизованный перевод англоязычного издания под названием A Guide to Matlab, 2** Edition, ISBN 0-521-61565-8, by Cambridge University Press (The Edinburgh Building, Cambridge CB2 2RU, UK). Copyright © B.Hunt, R.Lipsman, J.Rosenberg, K.Coombes, J.Osborn, and G.Stuck 2001, 2006. Русскоязычная версия, изданная ООО «Издательство Триумф». Все права защищены. © ООО «Издательство Триумф», 2008. Настоящее издание основано на тексте книги «Matlab. Официальный учебный курс Кембриджского университета» и издается по договору. © ООО«Издательство Триумф», 2008. ISBN 978-5-93673-095-5 © Обложка, серия и оформление ООО «Лучшие книги», 2008 ISBN 0-521-61565-8 (UK) © Видеокурс ООО «Лучшие книги», 2008 С НУЛЯ Зарегистрированный товарный знак ООО «Лучшие книги» (Свидетельство № 284271).
Краткое содержание Введение 11 ГЛАВА 1. Начало работы 17 ГЛАВА 2. Основы программы MATLAB 24 ГЛАВА 3. Взаимодействие с программой MATLAB 48 Практическое занятие А. Алгебра и арифметика 68 ГЛАВА 4. Выход за пределы основ 70 ГЛАВА 5. Графика программы MATLAB 86 Практическое занятие В. Исчисление, графика и линейная алгебра 109 ГЛАВА 6. Программирование 116 ГЛАВА 7. Публикация и М-книги 139 ГЛАВА 8. Программа Simulink 148 ГЛАВА 9. Графический интерфейс пользователя 163 ГЛАВА 10. Прикладные задачи 174 Практическое занятие С. Развитие навыков работы с программой MATLAB 240 ГЛАВА 11. Разрешение проблем 251 Ответы к практическим занятиям 265 Глоссарий 330 Минимальные системные требования, необходимые для запуска ВИДЕОКУРСА: Microsoft Windows 2000 / ХР, Pentium 300 МГц, видеокарта SVGA, разрешение 1024x768, 256 Мб RAM, дисковод CO-ROM 16x, звуковая карта, мышь, колонки. Вставьте CD-ROM диск с ВИДЕОКУРСОМ в дисковод; если в течение 1-2 мин. видеокурс не запустится, то запустите программу Проводник и откройте содержимое каталога компакт-диска в окне Проводника. Найдите файл Kurs.exe или Kurs в корневом каталоге CD-ROM диска и запустите его. Работа видеокурса тщательно тестировалась на множестве компьютеров и в различных версиях операционной системы Windows. Но при этом издательство не гарантирует правильную работу оболочки видеокурса на всех возможных аппаратных и программных конфигурациях различных компьютеров. Издательство гарантирует, что Вы сможете просмотреть все видеоуроки в стандартном плеере операционных систем Windows версий 2000/ХР. Для этого надо запустить плеер из главного меню операционной системы, в окне плеера выбрать команду Файл—Открыть (File—Open) и в появившемся диалоге указать путь к файлу нужного видеоурока с расширением .avi. Файлы видеоуроков находятся в каталоге \avi на компакт-диске, прилагаемом к книге.
Содержание Введение 11 Для чего написана эта книга 11 Для кого эта книга 12 Как составлена эта книга 12 Соглашения, используемые в этой книге 14 Об авторах 16 Благодарности 16 ГЛАВА 1. Начало работы 17 Платформы и версии 17 Установка 18 Запуск программы MATLAB 18 Ввод в окне Command Window (Командное окно) 19 Онлайновая справка 20 Окна программы MATLAB 23 Завершение сессии 23 ГЛАВА 2. Основы программы MATLAB 24 Ввод и вывод 24 Арифметика 25 Разрешение проблем 26 Ошибки при вводе 26 Прерывание вычислений 27 Алгебраическое или символьное счисление 27 Подстановка в символьных выражениях 28 Символьные выражения, точность переменной и точная арифметика 29 Векторы и матрицы 30 Векторы 31 Матрицы 32 Запрещение вывода 34 Функции 34 Встроенные функции 34 Функции, задаваемые пользователем 35 Управление переменными 36 Переменные и присваивание 39 Решение уравнений 40 Графика 43 Построение графиков командой ezplot 43
Содержание 7_ Видоизменение графиков 44 Построение графиков командой plot 45 Построение нескольких кривых 46 ГЛАВА 3. Взаимодействие с программой MATLAB 48 Интерфейс программы MATLAB 48 Рабочий стол 48 Рабочая область 49 Текущий каталог и путь поиска 50 Окно Command History (История команд) 51 М-файлы 53 М-файлы-сценарии 53 М-файлы-функции 56 Циклы 58 Представление результатов 59 Публикация М-файлов 59 Файлы-дневники 61 Интерактивные М-файлы 61 Продолжение на следующей строке длинных строк при вводе и выводе 62 Распечатка и сохранение графики 63 М-книги 64 Точная настройка М-файлов 66 Практическое занятие А. Алгебра и арифметика 68 ГЛАВА 4. Выход за пределы основ 70 Запрет вывода 70 Классы данных 71 Действия со строками 73 Символьные числа и числа с плавающей точкой 73 Функции и выражения 74 Подстановка 76 Дополнительно об М-файлах 76 Переменные в М-файлах-сценариях 76 Переменные в М-файлах-функциях 77 Структура М-файлов-функций 77 Комплексная арифметика 78 Дополнительно о матрицах 79 Решение линейных систем 79 Вычисление значений собственных и векторов собственных 79 Исчисление в программе MATLAB 80 Дифференцирование 80
8 MATLAB Интегрирование 81 Пределы 82 Суммы и произведения 83 Серия Тейлора 84 Переменные по умолчанию 85 ГЛАВА 5. Графика программы MATLAB 86 Двухмерные чертежи 86 Параметрические чертежи 86 Контурные и неявные чертежи 87 Чертежи полей 89 Трехмерные чертежи 90 Кривые в трехмерном пространстве 90 Поверхности в трехмерном пространстве 91 Окна изображений 93 Несколько окон изображений 93 Панель инструментов изображения 93 Объединение чертежей в одном окне 95 Настройка графики 96 Аннотирование 97 Изменение типа чертежа 99 Полная настройка 100 Изображения, анимация и звук 103 Изображения 103 Анимация 106 Звук 108 Практическое занятие В. Исчисление, графика и линейная алгебра 109 ГААВА6. Программирование 116 Ветвление 116 Ветвление с помощью команды if 116 Логические выражения 119 Ветвление с помощью команды switch 124 Более подробно о циклах 125 Неограниченные циклы 125 Прерывание цикла 126 Другие команды программирования 127 Подфункции 127 Массивы ячеек и структур 128 Команды для синтаксического разбора ввода и вывода 129 Вычисление и дескрипторы функций 131
Содержание 9_ Пользовательский ввод и вывод результата на экран 133 Отладка 135 Взаимодействие с операционной системой 136 Вызов внешних программ 136 Файловый ввод и вывод 137 ГЛАВА 7. Публикация и М-книги 139 Особенности процесса публикации 139 Более подробно об М-книгах 143 Элементы меню Notebook (Блокнот) 144 Графика М-книги 146 Дополнительные советы по эффективному использованию М-книг 146 ГЛАВА 8. Программа Simulink 148 Простое дифференциальное уравнение 148 Пример проектирования 154 Взаимодействие с рабочей областью 159 ГЛАВА 9. Графический интерфейс пользователя 163 Планировка GUI и инструмент GUIDE 163 Сохранение и запуск GUI 167 Возвратные функции GUI 169 ГЛАВА 10. Прикладные задачи 174 Освещение комнаты 175 Одна лампа на 300 ватт 175 Две лампы по 150 ватт 176 Три лампы по 100 ватт 180 Залоговые платежи 181 Моделирование Монте-Карло 187 Математическая генетика 193 Экспоненциальный рост/спад 193 Логистический рост 196 Повторный запуск модели с помощью программы Simulink 202 Линейные экономические модели 203 Линейное программирование 209 Маятник 360° 216 Уравнения движения 216 Увеличение начальной скорости 217 Нахождение начальной скорости, которая заставляет маятник совершать полные вращения 218 Численное решение теплового уравнения 220
jlO MATLAB Решение методом конечных разностей 221 Случай переменной проводимости 225 Решение с помощью программы Simulink 227 Решение с помощью команды pdepe 230 Модель транспортного потока 231 Практическое занятие С. Развитие навыков работы с программой MATLAB 240 ГААВА 11. Разрешение проблем 251 Общие ошибки 251 Неправильный или неожиданный результат 251 Ошибки синтаксиса 253 Ошибки написания 255 Сообщения об ошибках или предупреждения при построении графиков 256 Ранее сохраненный М-файл вычисляется по-другому 257 Компьютер не отвечает 258 Наиболее распространенные ошибки 258 Методики отладки 258 Ответы к практическим занятиям 265 Ответы к практическому занятию А: алгебра и арифметика 265 Ответы к практическому занятию В: исчисления, графика и линейная алгебра 275 Ответы к практическому занятию С: развитие навыков работы с программой MATLAB 297 Глоссарий 330 Операторы среды MATLAB 330 Встроенные постоянные 332 Встроенные функции 332 Команды среды MATLAB 333 Графические команды 341 Программирование вереде MATLAB 346 Команды программы Simulink 350 Блоки Программы Simulink 350
Введение Программа MATLAB представляет собой высокоуровневый технический вычислительный язык и интерактивную среду для разработки алгоритмов, визуализации и анализа данных, числовых расчетов. Используя программу MATLAB, вы можете решать технические вычислительные задачи гораздо быстрее, чем с помощью традиционных языков программирования, таких как С, C++ и Fortran. - MathWorks, Inc. Это утверждение - точка зрения компании MathWorks, Inc., являющейся разработчиком программы MATLAB. MATLAB 7 - программа для выполнения широкого круга математических задач. Программа содержит сотни команд для работы в области математики. Вы можете использовать MATLAB для построения графиков функций, решения уравнений, выполнения статистических тестов и многого другого. Это высокоуровневый язык программирования, который способен взаимодействовать с другими языками программирования, например, Fortran и С. Можно создавать звук и анимационную графику. Можно производить симуляцию и моделирование (особенно, если у вас есть доступ не только к основной программе MATLAB, но и к дополнительной программе Simulink). Вы можете подготавливать материалы для экспортирования в Интернет. Кроме того, вы можете использовать программу MATLAB для объединения математических вычислений с текстом и графикой с целью создания совершенных, интегрированных, интерактивных документов. Эта программа располагает множеством возможностей и параметров. В вашем распоряжении будут буквально сотни полезных команд. Справочная документация по программе MATLAB содержит тысячи записей. Стандартные ссылки на ресурсы, будь то руководство пользователя от MathWorks или другой источник, содержат множество таблиц с описанием большого количества команд, параметров и функций, которые ожидает получить пользователь для изучения или работы. Программа MATLAB - это более чем просто необычный калькулятор; эта программа является в высшей степени полезным и универсальным инструментом. Даже если вы только поверхностно знакомы с программой, вы можете использовать ее для выполнения невероятных вещей. Однако в своей специальной части программа предоставляет вам возможность определить, с какими из сотен команд, списков справочных страниц и тысяч элементов документации вам необходимо познакомиться и начать быстро и эффективно их использовать. Для чего написана эта книга Цель этой книги - научить вас быстро и успешно использовать программу MATLAB. Мы укажем вам разделы книги, которые вам необходимо знать, не перегружая вас излишними подробностями. Мы поможем вам избежать грубых ошибок. Мы предоставим вам примеры реального применения программы MATLAB, к которым вы сможете обратиться, когда будете выполнять собственную работу. Мы предоставим
12 MATLAB удобную справочную документацию для большинства полезных функций программы MATLAB. По окончании чтения этой книги вы сможете эффективно применять программу, а также будете готовы познакомиться с ней более глубоко. По окончании прочтения этой книги вы не станете экспертом по программе MATLAB, но вы получите необходимую подготовку для этого, если, конечно, именно это является вашей целью. Мы полагаем, что вас больше интересует возможность стать экспертом в вашей собственной специальности, будь то финансы или физика, психология или инженерия. Вы намереваетесь использовать программу MATLAB так же, как и мы, в качестве инструмента. Эта книга создана, чтобы помочь вам стать опытным пользователем программы MATLAB настолько быстро, насколько это возможно, и всегда иметь ее под рукой для использования в деле. Для кого эта книга Эта книга может быть полезной для абсолютных новичков, случайных пользователей, которые желают углубить свои знания, для пользователей среднего уровня и опытных пользователей, желающих узнать о новых возможностях программы MATLAB или узнать, как применяется программа Simulink, а также для экспертов, желающих узнать, известно ли нам что-то, что не известно им. Вы можете прочесть эту книгу, чтобы уметь использовать программу MATLAB для своих собственных целей. Если ваш работодатель (или ваш профессор) усадит вас перед компьютером с программой MATLAB и посоветует побыстрее научиться, как ее использовать, тогда вы сразу поймете, насколько полезна будет вам эта книга. Если вы преподаете или ходите на учебные курсы, где можно использовать программу MATLAB для работы над чем-либо другим - будь то математика, наука, инженерия, бизнес или статистика - эта книга будет вам хорошим подспорьем. Как ранее отмечалось, мы написали это руководство для использования его с программой MATLAB 7. Если вы намерены продолжать использовать MATLAB 5 или MATLAB 6, книга также будет вам полезной. Фактически, весь материал по командам MATLAB в этой книге соответствует всем этим версиям программы. Основными возможностями программы MATLAB 7, которые отсутствуют в более ранних версиях, являются анонимные функции, рассматриваемые в главе 2, и публикация, тема которой рассматривается в главах 3 и 7. Помимо этого, только небольшая часть материала по интерфейсу программы MATLAB, в основном, в главах 1, 3 и 9, не соответствует пятой версии программы. Как составлена эта книга В процессе написания этой книги мы использовали наш опыт, чтобы сосредоточиться на изложении важнейшей информации так быстро, насколько это возможно. Книга представляет собой краткое, концентрированное введение в программу MATLAB. В ней рассматриваются практические задачи (с полными решениями),
Введение 13 чтобы вы имели возможность проверить свои знания. Есть несколько разъясняющих примеров проектов, в которых демонстрируется, как программа MATLAB может использоваться в решении реальных задач, а также целая глава, посвященная разрешению проблемных ситуаций. Важнейшая часть книги содержит около 70 страниц - это главы с первой по четвертую и начало главы 5. Внимательно прочтите эту часть, и вы получите хорошее представление об основах программы MATLAB. Прочтите остальное - остаток главы «Графика», а также главы «Программирование», «Публикация», «Программа Simulink», «Графический интерфейс пользователя», «Приложения», «Разрешение проблем» - и вы узнаете достаточно, чтобы сделать что-нибудь стоящее с помощью программы MATLAB. Ниже представлена детализированная справка по содержанию книги. Глава 1, «Начало работы», рассматривает способы запуска программы MATLAB на разных платформах. В этой главе говорится, как вводить команды, получать доступ к онлайновой справке, как распознавать различные окна программы, с которыми вы будете сталкиваться, и как закрывать приложение. Глава 2, «Основы программы MATLAB», показывает, как производятся элементарные математические вычисления с помощью программы MATLAB. Эта глава содержит наиболее важные команды программы. Глава 3, «Взаимодействие с программой MATLAB», представляет собой введение в интерфейс рабочего стола программы MATLAB. Эта глава познакомит вас с основными функциями окон программы, с малыми программными файлами (М- файлы), которые вы будете использовать для наиболее эффективного применения программы, а также с некоторыми методами представления результатов работы с программой. После прочтения этой главы вы получите более четкое представление о безграничных возможностях программы, о чем упоминалось в цитате в начале «Введения». Практическое занятие А, «Алгебра и арифметика», содержит несколько простых задач для применения новоприобретенных навыков работы с программой MATLAB. Решения этих задач представлены в конце книги. Глава 4, «Выход за пределы основ», содержит объяснения некоторых моментов, важных для эффективного применения программы MATLAB. Глава 5, «Графика программы MATLAB», более подробно рассматривает многие команды программы MATLAB для создания графики. Практическое занятие В, «Исчисление, графика и линейная алгебра», предоставляет снова применить на практике изученный материал. Как и ранее, решения этих задач представлены в конце книги. Глава 6, «Программирование», познакомит вас с возможностями программирования в программе MATLAB. Эта глава организована таким образом, чтобы быть полезной как начинающему программисту, так и опытному специалисту, программирующему на языках Fortran и С.
U MATLAB Глава 7, «Публикация и М-книги», содержит введение в функции обработки текста и публикаций, доступные в программе MATLAB 7, с использованием М-файлов или команды publish, или путем комбинирования MATLAB с программой Microsoft Word. Глава 8, «Программа Simulink», описывает тесно связанную с MATLAB программу Simulink, графически ориентированный пакет для моделирования, симуляции и анализа динамических систем. Многие вычисления, осуществляемые в программе MATLAB, могут так же хорошо производиться в программе Simulink. Если у вас нет доступа к программе Simulink, вы можете пропустить главу 8. Глава 9, «Графический интерфейс пользователя», представляет собой введение в структуру и развертывание графических интерфейсов пользователя, используя программу MATLAB. Эта глава является немного более продвинутой, чем большая часть других. Глава 10, «Прикладные задачи», содержит примеры решения различных реальных задач из множества разных областей, с применением программ MATLAB и/или Simulink. Практическое занятие С, «Развитие навыков работы с программой MATLAB», содержит практические задачи, для решения которых используются методы и техники, освоенные вами в главах 6-10. Глава 11, «Разрешение проблем», является главой, к которой стоит обращаться всякий раз, когда что-то идет не так. Множество основных проблем может быть разрешено, если прочитать (или перечитать) материал данной главы. Далее идет раздел «Ответы к практическим занятиям», содержащий решения всех задач из трех практических занятий. Раздел «Глоссарий» содержит краткие описания (с примерами) многих команд программы MATLAB и объектов. Не являясь полноценной справкой, этот раздел все же представляет собой полезное руководство по наиболее важным возможностям программы MATLAB. И, наконец, последний раздел представляет собой полное оглавление. Соглашения, используемые в этой книге Мы используем специальные шрифты, чтобы отличать различные объекты. Символы, выводимые в программе MATLAB, отображаются шрифтом Courier New. Символы, используемые для обозначения переменных, формул, констант в тексте абзацев, а также команды, которые вы вводите для обработки в программе MATLAB, отображаются тем же шрифтом, но в полужирном начертании. Эти команды и ответы часто отображаются в двух строках, так, как это выглядит в программе MATLAB, например: >> х = sqrt B*pi + 1) х = 2.697
Введение 15^ Названия команд и функций MATLAB при их описании в тексте, выбираемые элементы меню (из строки меню на Рабочем столе MATLAB или в каком-либо окне) отображаются полужирным шрифтом Arial. Элементы подменю отделяются от элементов меню специальным значком, например, File ¦ Open (Файл ¦ Открыть). Надписи, например, заголовки окон и названия кнопок, отображаются полужирным шрифтом Arial. Имена файлов и папок, а также web-адресов, также отображаются полужирным шрифтом Arial, например: www.matlab.com. Все клавиши клавиатуры являются символами шрифта Keystroke, либо изображениями в графическом формате. Обращаем внимание читателя на то, что все примеры М-файлов, приведенные в книге, должны быть предварительно созданы в редакторе М-файлов и сохранены на диске. В книге используется шесть особых графических символов. Эти символы и их назначение приведены ниже. ^ Такие параграфы содержат перекрестные ссылки на другие части книги или предложение перейти к другой главе. ^ Такие параграфы содержат важные примечания. Наше любимое - «Почаще сохраняйте свою работу». На эти параграфы следует обратить пристальное внимание. •/ Такие параграфы содержат полезные подсказки или указывают на интересные возможности в рабочем окружении. Вам не обязательно обращать особое внимание на них при первом чтении, но, возможно, эти параграфы привлекут ваше внимание к некоторым особенностям программы MATLAB позже. ik Главы, разделы или задачи, начинающиеся с этого значка, являются немного более продвинутыми, чем остальные в этой книге, и при первом чтении их можно пропустить. \j± О В таких параграфах рассматриваются возможности Simbolic Math Toolbox (Инструментарий символьной математики), который используется для символьных (в отличие от цифровых) вычислений. Если вы не применяете Simbolic Math Toolbox (Инструментарий символьной математики), то можете пропускать эти разделы. Щ В таких параграфах рассматриваются возможности программы Simulink. Если вы не применяете программу Simulink, то можете пропускать эти разделы. Кстати, если вы студент и приобрели версию MATLAB Student Version, в этом случае Simbolic Math Toolbox (Инструментарий символьной математики) и программа Simulink будут автоматически включены в программный пакет, вместе с основной программой MATLAB.
JI6 MATLAB Об авторах Мы все являемся профессорами математики в университете Мериленда, Колледж Парк. Мы использовали программу MATLAB в наших исследованиях, в математических курсах, для презентаций и демонстраций, при создании графики для книги и для Интернета, и даже для помощи своим детям с домашним заданием. Мы надеемся, что вы сочтете MATLAB такой же полезной программой, как и мы, и что эта книга поможет вам научиться применять эту программу быстро и эффективно. Благодарности Мы благодарны за поддержку в наших исследованиях Национальному научному фонду, который на протяжении многих лет содействовал написанию этой книги. Наша работа над вторым изданием была частично поддержана грантами этого фонда DMS-0103647, DMS-0104087, АТМ-0434225 и DMS-0504212. Любые мнения, выводы и заключения или рекомендации, выраженные в данном материале, принадлежат авторам и не обязательно отражают точку зрения Национального научного фонда. Брайан Р. Хант Рональд Л. Липсмен Джонатан М. Розенберг Колледж Парк, Мериленд Январь, 2006
ГЛАВА 1 . Начало работы В этой главе мы познакомим вас с материалами, которые вам необходимы, чтобы начать эффективно использовать программу MATLAB. Материалы включают в себя: некоторые важные сведения из области компьютерных платформ и программного обеспечения, протоколы установки, запуск программы MATLAB, ввод команд и использование онлайновой справки, перечень разнообразных окон программы MATLAB и, наконец, завершение работы программы. Так как вы хотите поскорее начать применять программу MATLAB на практике, эта глава будет достаточно краткой. После того, как вы ее прочтете, вы сможете сразу приступить к главе 2, в которой найдете точные и простые инструкции по использованию программы MATLAB для производства математических вычислений. Интерфейс программы будет более подробно описан в главе 3. Платформы и версии Скорее всего, вы будете работать с программой MATLAB на компьютере с операционной системой Microsoft Windows или с какой-либо разновидностью операционной системы Unix (например, Linux). Некоторые предыдущие версии программы MATLAB (выпуски 11 и 12) не поддерживали платформу Macintosh, но большая часть текущих версий (выпуски 13 и 14) поддерживает эту платформу. Если у вас компьютер Macintosh, вы обнаружите, что наши инструкции для Windows отвечают большей части ваших требований и нужд. Программа MATLAB версий 6 (выпуск 12 и 13) и 7 (выпуск 14), в отличие от более ранних версий на этих разных платформах внешне выглядит одинаково. Для большей ясности мы предполагаем, что читатель использует компьютер под управлением операционной системы Windows. Те действительно немногие примеры, где наши инструкции будет необходимо отдельно применить к системам Linux, Unix или Macintosh, мы будем освещать особо. )/ Мы используем слово Windows по отношению ко всем разновидностям этой операционной системы. Программа MATLAB 7 (выпуск 14) будет работать под Windows 2000, Windows NT (версий 4.0 и выше) и Windows XP. Программа MATLAB 7 не будет работать под Windows 95, Windows 98 или Windows ME. Однако версия 6.5 программы MATLAB (выпуск 13) будет работать под Windows 98 или Windows ME. Эта книга написана в соответствии с текущей версией программы MATLAB, a именно MATLAB 7 (выпуск 14). Подавляющее большинство команд программы, описываемых нами, равно как и большое количество функций интерфейса MATLAB (например, редактор/отладчик М-файлов, и М-книги), соответствуют версии 6.5 (выпуск 13) и в некоторых случаях, более ранним версиям. В случае появления существенных различий между разными версиями мы будем особо отмечать такие моменты. Следует также отметить, что различия между версиями MATLAB Professional и MATLAB Student довольно невелики и внешне не заметны для новичка,
W MATLAB а иногда и для пользователя среднего уровня. В некоторых примерах, где мы будем описывать функцию программы MATLAB, которая доступна только в версии Professional, мы также особо выделим этот момент. Установка Если вы планируете запускать программу MATLAB, особенно версию Student, на своем собственном компьютере, то программу можно установить самостоятельно. Вы можете с легкостью выполнить установку, используя дистрибутивный установочный компакт-диск. Следуйте установочным инструкциям, как вы обычно это делаете при установке любой новой программы. В определенный момент в процессе установки на экране может возникнуть запрос, какие пакеты инструментов вы хотите установить. Если вы не испытываете недостатка пространства на жестком диске, мы советуем вам устанавливать все, что вас интересует, или то, что возможно понадобится в будущем. Согласуясь с целями данной книги, вам в любом случае следует установить пакет Simbolic Math Toolbox (Инструментарий символьной математики). Мы также советуем вам установить программу Simulink, которая рассматривается в главе 8. Запуск программы MATLAB Запуск программы MATLAB осуществляется так же, как и запуск любой другой программы. В операционной системе Windows вы можете получить доступ к программе через главное меню Пуск (Start), где программа будет обозначена именем MATLAB 7.0 или Student MATLAB. С другой стороны, у вас может быть ярлык программы на рабочем столе, который позволяет запустить программу с помощью двойного щелчка мышью на этом ярлыке. В системах Linux или Unix вам обычно достаточно ввести слово matlab в окно терминала, хотя, возможно, вам придется найти подкаталог bin в каталоге установки программы MATLAB, и добавить название этого подкаталога в наименование полного пути к файлу. Вы можете также воспользоваться ярлыком программы на рабочем столе, с помощью которого выполняется та же задача. Независимо от способа запуска программы, вы на короткое время увидите окно с изображением логотипа MATLAB и некоторой информацией, а затем запустится основное окно программы MATLAB, которое далее мы будем называть Рабочий стол. Это окно будет содержать строку заголовка (наименование программы - MATLAB), строку меню, панель инструментов и четыре внутренних окна, одно из которых скрыто. Самое большое и наиболее важное окно - Command Window (Командное окно) справа. В главе 3 мы более подробно рассмотрим использование и действия в трех других окнах: окно Command History (История команд), окно просмотра Current Directory (Текущая папка) и окно просмотра Workspace (Рабочая область). А сейчас мы остановимся на окне Command Window (Командное окно), чтобы вы как можно скорее начали работать с командами программы MATLAB. В верхней части окна Command Window (Командное окно) можно увидеть общую
Глава 1. Начало работы 19 информацию о MATLAB, возможно, в окне видны некоторые инструкции по началу работы или по доступу к справке, но, что важнее всего, вы увидите приглашение командной строки (>> или EDU>>). Если окно Command Window (Командное окно) активно, то строка заголовка окна будет темной, а после приглашения командной строки (далее просто приглашение) будет отображен текстовый курсор (мигающая вертикальная линия). Это та область, где вы будете вводить команды программы MATLAB (см. главу 2). Если же окно Command Window (Командное окно) не активно, щелкните на нем мышью в любом месте. На рисунке (Рис. 1.1) отображен пример открытого окна Рабочий стол вновь запущенной программы MATLAB. Current Directory ¦ >.,\MATtAB7l\work * X | flte- Edt Debug Desktop Window Help Г* Й Ef lal ? Current Directory: I D:\Program FilesWATLAB71 \work Command Window To get started, select MATLAB Help or Demos from the Help menu. Command History 4— 03.11.06 15:23 —4 Puc. 1.1. Окно программы MATLAB %/ Программа MATLAB 6 имеет окно Рабочий стол, но более старые версии, например, версия 5.3, не имеют такого интегрированного окна. Когда вы запускаете программу более старой версии, на экране отображается только окно Command Window (Командное окно). (В системах UNIX окно терминала, в котором вы запустили программу, становится окном Command Window (Командное окно).) Команды следует вводить в окне Command Window (Командное окно) в любой старой версии программы, так же, как и в одноименное окно в главном окне программы MATLAB - окне Рабочий стол. Ввод в окне Command Window (Командное окно) Щелкните мышью в окне Command Window (Командное окно), чтобы сделать окно активным. Когда окно станет активным, строка заголовка окна потемнеет, а в конце строки приглашения появится мерцающий текстовый курсор. Теперь вы
MATLAB 20 можете вводить команды. Попробуйте ввести 2+2, затем нажмите клавишу llEnter|. Затем попробуйте ввести команду factor A23456789) и, наконец, sin A00). Окно Рабочий стол программы MATLAB должно выглядеть, как на рисунке (Рис. 1.2). Wtf Щ f Current Directory: I D:\Program FilesWATLAB71 Work М— 03.11.06 15:23 - 2+2 factor A23456789) sin A00) Рис. 1.2. Окно программы MATLAB с информацией в окне Command Window (Командное окно) Онлайновая справка Программа MATLAB располагает исчерпывающей онлайновой справочной системой. Фактически, используя только эту книгу и онлайновую справку, вы вполне способны стать настоящим специалистом по MATLAB. Получить доступ к онлайновой справке можно несколькими способами. Если ввести в командной строке слово help, будет отображен длинный список разделов, для которых доступна справка. В качестве примера попробуйте ввести help general. Вы увидите длинный список основных значений команд MATLAB. Далее попробуйте ввести help factor, чтобы ознакомиться с командой factor. В каждом приведенном выше примере на экране отображается лишь малая часть всей информации. Вы можете использовать полосу прокрутки в правой части окна, чтобы просмотреть всю информацию. Или вы можете заставить программу MATLAB отображать информацию отдельными экранами, введя команду more one. Чтобы просмотреть следующий экран, нажимайте на клавишу II пР°бел для
Глава 1. Начало работы подробного просмотра введите команду help more. Команда more on блокирует все последующие команды до тех пор, пока вы не введете more off. С помощью команды lookf or производится поиск среди первых строк каждого файла справки программы MATLAB, с целью обнаружения определенной строки (используйте команду lookf or -all, чтобы произвести поиск среди всех строк). Например, если вам требуется просмотреть список всех команд MATLAB, которые содержат слово factor в качестве части имени команды или в кратком описании, тогда вам следует ввести lookf or factor. Если команда, которую вы ищете, отображается в списке, вы можете ввести help и наименование этой команды, чтобы получить о ней более полные сведения. Если команда help в окне Command Window (Командное окно) служит для получения сжатой информации об определенной команде, то более полная документация доступна через окно Help (Справка). Активировать это окно вы можете несколькими способами, например, введя команду doc в командной строке. Кроме того, этот инструмент доступен через команду меню Help (Справка) в строке меню. И, наконец, кнопка со знаком вопроса на панели инструментов также активирует окно Help (Справка). После запуска окна Help (Справка) вы увидите две панели. Первая из них называется Help Navigator (Навигатор справки); эта панель используется для поиска документации. Вторая панель, которую мы будем называть Display pane (Панель просмотра), используется для просмотра документации. Панель Display pane (Панель просмотра) работает почти так же, как обычный web-браузер. Эта панель имеет окно адреса, кнопки для перемещения вперед и назад (среди вызванных вами окон), гиперссылки для перемещения по всей документации, возможность хранения избранных страниц и другие полезные инструменты. Особенно удобно вызывать окно Help (Справка), вводя команды, например, doc sin. Эта команда запускает окно Help (Справка) и отображает страницу для значения sin. Страница соответствия для команды обычно представляет собой вполне доступный текст (через команду help), но иногда имеет больше информации. Вы можете также использовать Help Navigator (Навигатор справки) для нахождения документации, которую вы будете исследовать на панели отображения. Панель Help Navigator (Навигатор справки) имеет четыре вкладки, которые позволяют организовывать поиск документации разными способами. Первая вкладка, Contents (Содержимое), отображает в виде дерева все доступные разделы документации. Объем этого дерева будет определяться тем, как много пакетов вы или ваш системный администратор включили в исходную установку программы MATLAB. Вторая вкладка, Index (Указатель), отображает всю доступную документацию в формате индекса. Вкладка Index (Указатель) реагирует на клавишный ввод тех элементов, которые вы хотите исследовать в обычном режиме алфавитного реагирования. Третья вкладка, Searsh (Поиск), предоставляет поисковый механизм. Вы вводите предмет поиска, будь то функция или другой определяющий термин, и поисковый механизм обнаруживает документацию, включающую информацию
22 MATLAB с введенным вами значением. Последняя, четвертая вкладка, Demos (Демо), представляет собой небольшую коллекцию демонстрационных примеров, которые вы можете запустить, чтобы более глубоко познакомиться с программой MATLAB. Щелчок мышью на элементе, отображаемом на любой из этих вкладок, вызовет документацию об этом элементе на панель отображения. Окно Help (Справка) имеет отличное учебное руководство, описывающее его собственные функции. Чтобы увидеть это руководство, откройте окно Help (Справка) и выберите команду меню Help ¦ Using the Help Browser (Справка ¦ Использовать обзор справки). Окно Help (Справка) является мощным и простым в применении средством поиска информации, необходимой при использовании различных функций программы MATLAB. Этот инструмент таков, что, чем больше вы его используете, тем больше он вам нравится. Окно Help (Справка) изображено на рисунке (Рис. 1.3). Ffe Edit View Go Favorites Desktop Window He}p : Help navigator B-0 Release Notes Installation 0 MATLAB Excel Link MATLAB Builder for COM MATLAB Builder for Excel k-0 MATLAB Compiler $L-0 MATLAB Distributed Computing ЕпЦ $¦¦0 MATLAB Report Generator Щ0 MATLAB Web Server 0 Communications Toolbox Control System Toolbox $-0 Data Acquisition Toolbox B-0 Database Toolbox $-0 Datafeed Toolbox Distributed Computing Toolbox B-0 Filter Design Toolbox ф 0 Filter Design HDL Coder Ь-0 Financial Toolbox Щ-0 Financial Derivatives Toolbox Щ-0 Financial Time Series Toolbox Ы-0 Fixed-Income Toolbox <\AU — ¦: ..I ТИк j Release 14 with Service Pack 3. Begin Her If You Are Upgrading from a Previous Release... ¦ Release Notes Highlights new features, installation notes, bug fixes, and compatibility issues. If You Are Using MATLAB for the First Time... At the heart of MATLAB is a new language that you must learn before you can fully exploit its power. This isnt as hard as it might sound; you can learn the basics of MATLAB very quickly. You will be rewarded with high-productivity, high-creativity computing power that will change the way you work. If you are a first-time user, the best way to get started is to read thoroughly the Gettmq Started with MATLAB tutorial with MATLAB open so you can follow along. The tutorial book comes with MATLAB and is available in PDF and for purchase on the MathWorks Web site. If you dont want to take the time to read it thoroughly, here are links to the most important sections: Рис. 1.3. Окно Help (Справка) программы MATLAB •/ Если вы работаете с программой MATLAB версии 5.3 или более ранней, ввод команд help, help general и help factor в командной строке будет работать, как описано выше. Окно Help (Справка) не будет доступно, но с помощью команд helpwin и helpdesk можно вызвать справку в более примитивных, хотя не менее полезных окнах. Если вы терпеливы и не слишком стремитесь перейти к главе 2, вы можете ввести команду demo, чтобы поэкспериментировать с некоторыми онлайновыми демонстрациями программы MATLAB.
Глава 1. Начало работы 23 Окна программы MATLAB Мы уже рассмотрели программные окна Command Window (Командное окно) и Help (Справка), а также мимоходом упомянули об окне Command History (История команд), окнах Current Directory (Текущая папка) и Workspace (Рабочая область). Эти и некоторые другие окна, с которыми вы столкнетесь при работе с программой MATLAB, позволят вам делать следующее: управлять файлами и папками, к которым вам и программе MATLAB будет нужен доступ; записывать и редактировать маленькие подпрограммы MATLAB (М-файлы), которые вы будете использовать для эффективной работы MATLAB; отслеживать переменные и функции, заданные вами в процессе работы; отображать и манипулировать графикой; создавать модели для решения задач и симуляции процессов. Некоторые из этих окон запускаются отдельно, а некоторые встроены в главное окно Рабочий стол. Те окна, которые запускаются отдельно, вы можете закрепить в окне Рабочий стол, с помощью собственных меню Desktop (Рабочий стол) этих окон, или щелкнув мышью на направленной вниз изогнутой стрелке на их панелях инструментов. Вы можете удалить окна, встроенные в главное окно Рабочий стол программы MATLAB, и использовать эти окна отдельно, щелкнув мышью на направленной вверх изогнутой стрелке в верхнем правом углу панели инструментов окна. Более полно эти возможности рассматриваются в последующих главах. А теперь мы хотим привлечь ваше внимание к другому важному типу окна, с которым вы столкнетесь, а именно, к графическим окнам. Многие из команд, которые вы используете, будут генерировать графики или изображения. Они будут отображаться в отдельном окне, называемом окном изображения. В главе 5 мы научим вас наиболее эффективно генерировать и манипулировать окнами изображений программы MATLAB. Простой пример окна изображения показан на рис. 2.1 в главе 2. )/ В программе MATLAB 6 или в более ранней версии вы не сможете закреплять окна изображений. Та же картина наблюдается и в версии 7, если вы используете платформу Macintosh. Завершение сессии Простейший способ завершить сессию MATLAB - ввести команду quit в командной строке. Вы можете также щелкнуть мышью на кнопке, которая обычно закрывает окна (значок [х] в верхнем правом углу окна). Еще один способ выхода - использовать команду меню File ¦ Exit MATLAB (Файл ¦ Закрыть MATLAB) в окне Рабочий стол. Перед закрытием программы MATLAB следует убедиться, что вы сохранили свою работу, распечатали графику или другие необходимые файлы и убрали за собой программный мусор. Этот вопрос рассматривается в главе 3.
ГЛАВА 2. Основы программы MATLAB В этой главе вы познакомитесь с применением программы MATLAB для математических расчетов. Мы рекомендуем вам читать эту главу в процессе работы с программой. Работайте с командами параллельно с чтением. Свободно экспериментируйте с вариантами примеров. Лучший способ узнать, как программа реагирует на команду - это применить данную команду. ^ Для дальнейшей практики вы можете поработать с задачами в Практическом занятии А. Вы можете также обратиться к Глоссарию для ознакомления с краткими описаниями операторов, констант, функций, команд и программных инструкций. Ввод и вывод Команды в программе MATLAB вводятся в окне Command Window (Командное окно). Программа возвращает результат двумя способами: текст или числовой результат возвращается в том же самом окне Command Window (Командное окно), но графический результат отображается в отдельном окне изображения. Образец экрана с окном Рабочий стол и окном изображения, озаглавленным Figure 1 (Рисунок 1), показан на Рис. 2.1. Чтобы сгенерировать такой экран на своем компьютере, сначала введите 1/2 + 1/3. Затем введите ezplot ('хА3 - х#). Рис. 2.1. Окна программы MATLAB
Глава 2. Основы программы MATLAB 25 • Пока программа MATLAB работает, может отображаться символ ожидания - например, песочные часы отображаются во многих операционных системах. Программа может также не подавать никаких внешних признаков до тех пор, пока не закончит вычисления. Арифметика Как уже упоминалось выше, вы можете использовать программу MATLAB для арифметических расчетов, как калькулятор. Вы можете прибавлять с помощью знака +, отнимать со знаком -, умножать со знаком *, делить со знаком / и возводить в степень со знаком Л. Например: >> 3А2 - E+4)/2 + 6*3 ans = 22.5000 Программа MATLAB выводит ответ и обозначает значение в виде переменной, называемой ans. Если вы захотите выполнить дальнейшие вычисления с полученным ответом, вы можете использовать переменную ans, вместо того, чтобы заново вводить числовое значение. Например, вы можете вычислить сумму квадрата полученного ответа и его квадратного корня, как показано ниже: >> ansA2 + sqrt (ans) ans = 510.9934 Заметьте, что программа MATLAB присваивает новое значение переменной с каждым вычислением. Чтобы выполнять более сложные вычисления, вы можете присваивать вычисленные значения переменным по вашему выбору, например: >> u = cos A0) и = -0.8391 >> v = sin A0) v = -0.5440 >> uA2 + vA2 ans = 1 • Следует отметить, что в тригонометрических функциях в программе MATLAB используются радианы, а не градусы. Программа MATLAB использует арифметику двойной точности с плавающей точкой, при чем точность сохраняется приблизительно до 15 знака; однако по умолчанию MATLAB отображает только 5 знаков. Чтобы отобразить больше
26 MATLAB знаков, введите команду format long. Тогда все последующие числовые результаты будут иметь 15 знаков после точки. Чтобы вернуться к пятизначному отображению, введите команду format short. Программа MATLAB отличается от калькулятора тем, что способна производить точные арифметические вычисления. Например, программа MATLAB может символически сложить дроби 1/2 и 1/3, чтобы получить правильную дробь 5/6. Мы рассмотрим, как это делается, в разделах «Символьные выражения», «Точность переменной» и «Точная арифметика» далее в этой главе. Разрешение проблем При использовании какой-либо математической программы вы неизбежно столкнетесь с некоторыми проблемами. Даже при вводе простых арифметических команд вы можете случайно ошибиться или нечаянно нарушить правило программы MATLAB. В этом кратком разделе мы покажем три способа, чтобы справиться с такого рода проблемами. Ошибки при вводе Если вы сделаете ошибку в строке ввода, программа MATLAB выведет на экран сообщение об ошибке. Например, вот что произойдет, если вы попробуете вычислить следующее: >> ЗиА2 3u Л 2 Error: Missing MATLAB operator. Ошибка состоит в отсутствии оператора умножения *. Выражение будет выглядеть правильно таким образом: 3*иА2. Обратите внимание, что программа помещает маркер (вертикальную черту) в том месте, где должна быть ошибка; однако реальная ошибка может присутствовать в выражении до или после этого знака. • Сообщение об ошибке, создаваемое в программе MATLAB 7.0.4 (последнее обновление на момент написания книги), представляет собой нечто другое. Вы обнаружите, что сообщения об ошибках и предупреждения, с которыми вы столкнетесь, будут различаться в зависимости от версии программы. ^ Отсутствующие операторы умножения и скобки являются наиболее частыми ошибками ввода у начинающих пользователей. ^ Вернитесь к обсуждению онлайновой справки в главе 1. Если вы не можете расшифровать сообщение об ошибке, сгенерированное при введении команды программы MATLAB, обратитесь к онлайновой справке для этой команды или используйте функцию поиска в окне Help Browser (Обзор справки).
Глава 2. Основы программы MATLAB 27 Вы можете редактировать строку ввода, используя клавишу ijj, чтобы вновь отобразить предыдущую команду, затем можете исправить команду с помощью клавиш Н и '?*] и нажать клавишу iF"^rl. Клавиши со стрелками вертикального перемещения позволяют производить прокрутку вперед и назад всех команд, которые вы ввели во время сессии MATLAB, и очень полезны, когда вам необходимо откорректировать, изменить или заново ввести предыдущую команду. Прерывание вычислений Если программа MATLAB «зависает» во время вычисления или вам кажется, что операция выполняется программой слишком долго, вы можете произвести прерывание операции, нажав сочетание клавиш 11 Ctrl 1+ С|. то есть, удерживая нажатой клавишу ': Ctrl I. нажать клавишу ij^J. Несмотря на то, что это достаточно небезопасно, это один из методов прерывания работы, когда программа MATLAB не отвечает. Алгебраическое или символьное счисление f~^--$ Используя инструмент Simbolic Math Toolbox (Инструментарий символьной математики), вы можете осуществлять алгебраические или символьные вычисления, такие как разложение на множители или решение алгебраических уравнений. Чтобы убедиться, что Simbolic Math Toolbox (Инструментарий символьной математики) установлен на вашем компьютере, введите в командной строке help simbolic. Для выполнения символьных вычислений вам необходимо использовать команду syms, чтобы задать переменные, которые вы планируете использовать в качестве символьных. Рассмотрите следующую серию команд: >> syms х у » (х-у)*(х-у)*2 ans = (х-у)А3 > > expand(ans) ans = хл3-3*хА2*у+3*х*ул2-ул3 >> factor(ans) ans = (х-уГЗ
2Ь MATLAB • Обратите внимание, что символьный вывод выровнен слева, тогда как числовой вывод жестко определен. Эта возможность бывает очень полезна, когда необходимо отличить символьный вывод от числового. Хотя программа MATLAB делает небольшие упрощения во вводимых вами выражениях, тем не менее, MATLAB не сделает большего, даже если вы этого захотите. Команда expand заставляет программу MATLAB разложить выражение на множители, а команда factor - восстановить краткую прежнюю форму. Программа MATLAB имеет команду, называемую simplify, которую вы иногда можете использовать для максимально простого выражения формулы, например: >>simplify ((хА3-уА3)/(х-у)) ans = хЛ2+х*у+уЛ2 |/ Программа MATLAB имеет еще более подходящую команду, simple, которая иногда действует лучше, чем simplify. Попробуйте применить обе команды к тригонометрическому выражению sin(x) *cos(y) + cos(x) *sin(y), чтобы сравнить результаты. Для полного понимания ответа вам придется прочитать раздел онлайновой справки по команде simple. Подстановка в символьных выражениях Когда вы работаете с символьными выражениями, вам часто бывает необходимо заменять числовое значение или даже другое символьное выражение одной (или более) исходной переменной в выражении. Это делается с помощью команды subs. Например, предположим, что задано символьное выражение w, включающее в себя символьную переменную и. Тогда команда subs (w, u# 2) заменит значением 2 переменную и в выражении w. Вот еще несколько примеров: >> d » w » a = l = 1 w = u = 2 - vA subs ans = 4 » - vA2 subs ans = 2-1 # A2 2 (w (w syms # u# u 2) d)
Глава 2. Основы программы MATLAB 29 >> subs (w, v# u + v) ans = иЛ2 - (u + v)/42 >> simplify (ans) ans = - 2*u*v - vA2 %/ Когда вы вводите много команд в одной строке, разделяя их запятыми, программа MATLAB выполняет каждую команду и отображает результаты в отдельных строках. В приведенном примере в первой строке ввода вторая команда не выводит результат, таким образом, мы видим результат выполнения только первой команды. Символьные выражения, точность переменной и точная арифметика Как мы уже отмечали ранее, программа MATLAB в своих вычислениях использует арифметику с плавающей точкой. Используя Symbolic Math Toolbox (Инструментарий символьной математики), вы тоже можете выполнять точные арифметические вычисления с помощью символьных выражений. Рассмотрите следующий пример: >> cos (pi/2) ans = 6.1232е-17 Ответ выведен в формате с плавающей точкой и означает 6.1232 Ч 10 17. Однако мы знаем, что cos (тт/2) равен нулю. Неточность вычисления происходит из-за того, что константа pi в программе MATLAB дается с приближением к тг с точностью до 15 знака, но не с точным его значением. Чтобы вместо приближенного получить точный результат, нам необходимо создать точное символьное представление выражения (тт/2), введя команду sym ( 'pi/2 '). А теперь попробуем получить косинус символьного представления тт/2: » cos (sym ( 'pi/2')) ans = 0 Это и есть ожидаемый ответ. Кавычки, в которые заключено выражение pi/2 в команде sym ( 'pi/2 '), создают строку, содержащую символы pi/2, и не позволяют программе MATLAB вычислить pi/2 в виде числа с плавающей точкой. Команда sym превращает строку в символьное выражение.
_30 MATLAB Команды sym и syms тесно связаны. Фактически, команда syms x будет эквивалентна команде х = sym ( 'xr). Команда syms оказывает длительный эффект на свой аргумент. Фактически, даже если значение х было заранее задано, команда syms х аннулирует эту заданность и сформирует из значения х символьную переменную, которая и остается символьной, пока не будет задана вновь. С другой стороны, команда sym имеет только временный эффект, если только вы не привяжете вывод результата к переменной, как это показано в выражении х = sym ('х'). Ниже показано, как можно сложить в символьной форме 1/2 и 1/3: » sym ('1/2') + sym ('1/3') ans = 5/6 Наконец, вы можете также выполнять арифметические вычисления переменной точности с помощью команды vpa. Например, чтобы получить результат вычисления V2 с точностью до 50 знака после запятой, введите следующее: » vpa ('sqrt B) ',50) ans = 1.414213 562373 0950488016887242096980785696718753769 Если вы не зададите количество знаков, то по умолчанию будет установлено количество 32. Вы можете изменить установку по умолчанию с помощью команды digits. О Вам следует с осторожностью использовать команды sym или vpa в выражениях, которые программа MATLAB должна обработать перед применением вычисления с переменной точностью. Например, вычислите выражения 3Л45, vpa CЛ45) и vpa ( Г3Л45Г). Первое выражение даст приблизительный результат с плавающей точкой, второе, поскольку программа MATLAB вычисляет выражения со степенями с точностью до 16 знака, даст ответ, который будет верным только в пределах первых 16 знаков после запятой, а третье выражение даст точный результат. °^ Смотрите раздел «Символьные числа и числа с плавающей точкой» в главе 4У чтобы узнать более подробно о том, как программа MATLAB осуществляет конвертацию между символьными числами и числами с плавающей точкой. Векторы и матрицы Изначально программа MATLAB была написана, чтобы позволить математикам, ученым и инженерам работать с объектами линейной алгебры, то есть векторами и матрицами, настолько просто, насколько это вообще возможно. В данном разделе мы познакомим вас с этими понятиями.
Глава 2. Основы программы MATLAB Векторы Вектор - это упорядоченный перечень чисел. В программе MATLAB вы можете ввести вектор любой длины, введя перечень чисел, отделенных запятыми или пробелами, помещенный в квадратные скобки. Например: >> Z = [2,4,6#8] Z = 2 4 6 8 » Y = [4 -3 5 -2 8 1] Y = 4-35-281 Предположим, вы хотите создать вектор со значениями от 1 до 9. Ниже показано, как это сделать, не вводя последовательно каждое число: » X = 1:9 X = 12 3 4 5 б 7 8 9 Условное выражение 1:9 используется для представления вектора чисел от 1 до 9 с приращением на 1. Приращение может быть задано в виде среднего из трех аргументов: >> X = 0:2:10 X = О 2 4 6 8 10 Приращение может быть дробным или отрицательным, например, 0:0.1:1 или Элементы вектора X можно выделить в виде X A), X B) и т.д. Например: » X C) ans = 4 Чтобы изменить форму вектора X со строчной на столбцовую, введите символ (') после X. » X' ans = 0 2
32 MATLAB 4 6 8 10 Вы можете выполнять над векторами математические операции. Например, чтобы возвести в квадрат элементы вектора X, введите следующее: >> Х.А2 ans = 0 4 16 36 64 100 Точка в данном выражении играет очень важную роль; она показывает, что числа вектора X должны возводиться в квадрат по отдельности, то есть элемент за элементом. Если бы вы ввели команду ХА2, была бы совсем другая картина. Эта команда заставила бы программу MATLAB использовать матричное умножение, чтобы умножить значение X само на себя, и в этом случае программа вывела бы сообщение об ошибке. (Тема матриц будет рассмотрена ниже, а также в уроке 4.) Аналогично этому, введите .* или ./, если вы хотите умножить или разделить векторы элемент за элементом. Например, чтобы умножить элементы вектора X на элементы вектора Y, введите следующее: ans = 0 -6 20 -12 64 10 Большинство операций в программе MATLAB выполняются элемент за элементом. Например, вы не вводите точку перед операторами сложения и вычитания, и можете ввести ехр (X), чтобы возвести в степень все числа вектора X (матричная функция возведения в степень выглядит так: expm). Одной из важных возможностей программы MATLAB является способность эффективно выполнять операции с векторами. Матрицы Матрица - это прямоугольный набор чисел. Строчные и столбцовые вектора, которые мы рассматривали выше, являются примерами матриц. Рассмотрим матрицу размером 3Х4: '12 3 4" 5 6 7 8 9 10 11 I!
Глава 2. Основы программы MATLAB 33 8 программе MATLAB эту матрицу можно ввести с помощью следующей команды: » А = [1, 2, 3, 4; 5# 6, 7, 8; 9, 10# 11, 12] А = 12 3 4 5 6 7 8 9 10 11 12 Обратите внимание, что элементы матрицы в строке отделяются друг от друга запятыми, а сами строки разделяются точкой с запятой. Элементы в строке можно также отделять друг от друга пробелами. Если матрицы А и В имеют одинаковый размер, сумма матриц (элемент за элементом) получается путем ввода команды А + В. Вы можете также произвести операцию сложения матрицы со скаляром (отдельным числом); команда А + с прибавит с к каждому элементу А. Аналогично, с помощью команды А - В можно получить разность матриц А и В, а при введении команды А - с число с будет отнято от каждого элемента матрицы А. Если матрицы А и В совместимы по множителю, то есть если А представляет nxm, а В представляет mxl, то произведение матриц А*В будет соответствовать выражению nxl. Вспомните, что элемент А*В в строке i и в столбце j является суммой произведений элементов из строки i матрицы А и элементов столбца j матрицы В. т (A*B)iJ=Y,AikB?,\<i<n,\<j<l. к=\ Произведение числа с на матрицу А получается с помощью команды с*А, а выражение А' представляет собой транспозицию матрицы А. (Для получения более полной информации обратитесь к онлайновой справке для команд ctranspose и transpose.) Простой пример представляет собой произведение матрицы А Cx4) и столбцового вектора Z ' Dx1): >> A*Zr ans = 60 140 220 Результатом будет матрица 3*1, иначе говоря, столбцовый вектор. ^ Программа MATLAB имеет много команд для операций с матрицами. Прочитать о них вы можете в разделе «Дополнительно о матрицах» в главе 4, а также в онлайновой справке; некоторые из них представлены в разделе «Линейные экономические модели» в главе 10. 2-1605
34 MATLAB Запрещение вывода Ввод точки с запятой в конце строки ввода приводит к запрещению вывода результата команды MATLAB. Точка с запятой обычно должна использоваться при определении больших векторов или матриц (например, X я -1:0.1:2;). Точка с запятой может также использоваться в некоторых других ситуациях, когда не требуется отображение вывода результатов. Функции В программе MATLAB вы будете использовать как встроенные функции, так и функции, созданные вами. Встроенные функции Программа MATLAB имеет много встроенных функций. В их число входят функции sqrt, cos, sin, tan, log, exp и at an (для функции арктангенс), а также более специализированные математические функции, такие как gamma, erf и bes- selj. Программа MATLAB имеет также некоторые встроенные константы, включая pi (число тт), i (комплексное число i = V-1) и Inf (°° - бесконечность). Ниже показано несколько примеров: » log (ехр(З)) ans = 3 Функция log является натуральным логарифмом и во многих текстах называется In. » sin B*pi/3) ans = 0.8660 Чтобы получить точный ответ, вам необходимо использовать символьный аргумент. » sin (syxn ('2*pi/3')) ans = 1/2*3ЛA/2)
Глава 2. Основы программы MATLAB 35^ Функции, задаваемые пользователем В этом разделе мы проверим два способа задания ваших собственных функций в программе MATLAB. Первый способ использует команду Inline, а второй использует оператор <?, чтобы создать так называемую «анонимную функцию». Второй метод является новым в программе MATLAB 7, и в настоящее время этому методу отдается предпочтение. Периодически мы будем упоминать о команде inline ради пользователей более ранних версий программы. Однако мы настоятельно рекомендуем пользователям MATLAB 7 и пользователям более ранних версий, когда они обновят программу, использовать оператор @ в качестве обычного метода для задания функций. Функции можно также задавать в отдельных файлах, которые называются М-файлами (см. главу 3). В этом примере показано, как задается функция f (x) ¦ х2 с использованием этих команд. » f = <? (х) хА2 f = @ (х) хл2 Можно сделать и по-другому: » fl = inline ('хА2','х') fl = Inline function: fl(x) = хл2 Когда функция задана, не важно каким методом, вы можете ее вычислить, например: » f D) ans = 16 » fl D) ans = 16 Как мы отмечали ранее, большинство функций программы MATLAB могут оперировать как векторами, так и скалярами. Чтобы быть уверенным, что заданная вами функция может оперировать с векторами, вставляйте точки перед математическими операторами *, / и А. Таким образом, чтобы получить векторизованную версию функции f (x) ¦ х2, введите строку
_36 MATLAB »f = <? (x) x.A2 или строку >> fl = inline ('x#A2','x') Теперь мы можем вычислить любую функцию для вектора, например: » f A:5) ans = 1 4 9 16 25 Используя графические возможности программы MATLAB, вы можете начертить графики функций ? и ?1. Это можно сделать несколькими способами, которые мы рассмотрим в разделе «Графика» далее в этом уроке. В завершении этого раздела отметим, что функции можно также задавать с двумя или более переменными. Например, решение любой из этих функций » g = @(х, у) хА2 + уА2; g A, 2); » gl = inline (rxA2 + yA2', 'x', 'у'); gl A, 2) даст ответ 5. Если вместо этого вы зададите функцию следующим образом »д = @(х# у) х,А2 + у.А2; тогда вы сможете вычислить векторы; таким образом, выполнение следующего выражения » g ([1 2], [3 4]) ans = 10 20 дает значения функции в точках A, 3) и B, 4). Управление переменными К текущему моменту мы познакомились с четырьмя различными типами данных программы MATLAB: числами с плавающей точкой, строками, символьными выражениями и функциями. При длительной сессии программы MATLAB может быть нелегко запомнить имена и типы всех переменных, которые вы задали. Вы можете ввести команду whos, чтобы просмотреть общий список имен и типов, или классов, ваших заданных на текущий момент переменных. Но перед тем как сделать это, произведите присвоения а = pi, b = rpi ', с = ('pi r), а затем введите whos. Ниже показан вывод результатов сессии программы MATLAB, отображенной в этой главе.
Глава 2. Основы программы MATLAB 37 >> whos Name А X Y Z а ans b с d t-ti fl g gi u V w X У Size 3x4 1x31 1x6 1x4 lxl 1x2 1x2 1x2 lxl lxl lxl lxl lxl lxl lxl lxl lxl lxl Bytes 96 248 48 32 8 16 4 4 8 16 824 16 882 126 126 138 126 126 Class double array double array double array double array double array double array char array char array double array function handle array inline object function handle array inline object sym object sym object sym object sym object sym object Grand total is 182 elements using 2844 bytes Переменным A, X, Y, Z, а и d были присвоены числовые значения и они обозначены как «двойной массив». Это означает, что они являются массивами чисел с двойной точностью; в данном случае массивы and имеют размер Iх 1, то есть, являются скалярами. Столбец Bytes (Байты) показывает, сколько компьютерной памяти занимает каждая переменная. Переменная ans также является числовой, поскольку последний вывод был вектором 1Х2. Переменная b является строкой, обозначенной как char array (Символьный массив), так как переменные с, u, v, w, х, у являются символьными. Наконец, мы видим также два массива обработки функции и два массива встроенных объектов, соответствующие парам анонимных функций и встроенных функций. Команда whos показывает сведения обо всех заданных переменных, но эта команда не показывает значения переменных. Чтобы увидеть значение переменной, достаточно просто ввести название переменной и нажать клавишу Fnterl.
38 MATLAB При вводе командам программы MATLAB требуются определенные классы данных, и очень важно знать, какой именно класс данных требуется данной команде; справочный текст по команде обычно содержит класс или классы, которые требуются при вводе. Неверный класс ввода обычно приводит к появлению сообщения об ошибке или к неожиданному результату. Например, введите команду sin ( 'pi '), чтобы увидеть, к какому результату может привести добавление строки в функцию, которая не приемлет строк. Чтобы очистить все заданные переменные, введите clear или clear all. Вы можете также ввести, например, clear x у, чтобы очистить только переменные х и у. flte. €<fc Shortens Worfcsp* Debus Desktop Window Help <& % Ht ^ °* К tt Ш How to Add S Where New ce l« ¦A Sx ' a ]ant i fa e d да jL o9 51 u 3v в Ы \x |y <3x4 doubfe> <1x31 double> И-Э5-2 81] [2 4 6 8] 3.1416 [10 20] 'Pi' \ (8) M к Л2 <1x1 inline> <1 xi inline^ <1x1 sym> <1x1 sym> <1x1 sym> <1x1 sym> <1x1 sym> j^j Currert Directory j ¦kl . . .mm У j Current Ofe'ftCtory: ] Df roqratm Fiies\MATLAB71 \v X » |c d ri d d d d Name A X Y Z a ans Ь с d t fl gi u V w X 7 Size 3x4 1x31 1x6 lxl 1x2 1x2 1x2 lxl lxl lxl lxl lxl lxl lxl lxl lxl lxl Grand total is 182 elements using -laixil 'Ofk l\ J & тЯШЯШШШЯшШЯШЯВ Bytes Class 96 double arr 248 double arr 48 double arr 32 double arr 8 double arr 16 double arr 4 char array 4 char arra; 6 double arr ay ay : ay «7 • ay 16 function handle array 824 inline object 16 function handle array 882 inline object 12 6 sym object 126 sym object 136 sym object 126 sym object 126 sym object 2844 bytes i 4 Puc. 2.2. Рабочий стол с окном Workspace (Рабочее пространство) Обычно следует очищать переменные перед началом новых вычислений. В противном случае значения из предыдущих вычислений могут случайно попасть в новые. Окно Workspace (Рабочее пространство) предоставляет графическую альтернативу команде whos. Вы можете активировать это окно, щелкнув мышью на вкладке Workspace (Рабочее пространство) в окне Current Directory (Текущий каталог), или введя команду workspace в командной строке. На Рис. 2.2 показан Рабочий стол, в котором окна Command Window (Командное окно) и Workspace (Рабочее пространство) содержат ту же самую информацию, которая отображена выше.
Глава 2. Основы программы MATLAB 39^ Переменные и присваивание В программе MATLAB для присвоения значений переменной используется знак равенства. Например, это действие >> х = 7 х = 7 придает переменной х значение 7. Теперь, где бы программа MATLAB ни обнаружила букву х, MATLAB будет подставлять значение 7. Например, если переменная у была задана, как символьная переменная, получим следующий результат: » хА2-2*х*у + у ans = 49-13*у Вы можете произвести основные присвоения для символьных переменных, а затем манипулировать ими: >> syms х у >> z « хА2 - 2*х*у + у Z = хА2 - 2*х*у + у » 5*y*z ans = 5*у*( хА2 - 2*х*у + у) Имя переменной или имя функции могут представлять собой любую строку или буквы, цифры, символы подчеркивания, при условии, что они начинаются с буквы (знаки пунктуации исключены). Программа MATLAB различает буквы верхнего и нижнего регистров. Вам следует выбирать запоминающиеся имена, используя в основном буквы нижнего регистра. Например, вы могли бы использовать слово cubicsol в качестве имени решения кубического уравнения. ?> Основным источником запутанных ошибок является невнимательность при повторном использовании ранее заданных переменных. Программа MATLAB никогда не забывает ваши установки, если только не изменить настройки. Вы можете проверить текущее значение переменной, просто введя имя этой переменной.
40 MATLAB Решение уравнений Вы можете решать уравнения, содержащие переменные, с помощью команд solve и f zero. Например, чтобы решить квадратное уравнение х2 - 2х - 4 = О, введите следующее: » solve (rxA2 - 2*х -4 = 0') ans = Обратите внимание, что уравнение, которое требуется решить, задано как строка, то есть взято в одинарные кавычки. Ответ представляет собой точное (символьное) решение 1+V5. Для получения числовых решений введите double (ans) или vpa (ans), чтобы отобразить больше знаков. Ввод с командой solve может также быть символьным выражением, но в этом случае программа MATLAB потребует, чтобы правая часть выражения была заключена в скобки, и фактически синтаксис решения уравнения х2 - Зх = -7 будет выглядеть так: >> syms х >> solve (xA2 - 3*х + 7) ans = 3/2+1/2*1*19ЛA/2) 3/2-l/2*i*19/4(l/2) Ответ представляет собой точное (символьное) решение C + Vl9i)/2 (сложные числа, где буква i в ответе ставится для мнимой единицы V-1). Для получения числовых решений введите double (ans) или vpa (ans), чтобы отобразить больше знаков. С помощью команды solve можно решать высокоуровневые полиномиальные (многочленные) уравнения, равно как и многие другие типы уравнений. Можно также решать уравнения, содержащие более чем одну переменную. Если уравнений меньше, чем переменных, вам следует определить (как строки), какую переменную (переменные) требуется вычислить. Например, введите solve ( '2*х - log (у) = 1Г# гуг), чтобы решить уравнение 2х - log у = 1 для переменной у при условии х. Подобным образом вы можете определить более чем одно уравнение. Например: » [X/ у] = solve (гхА2 - у = 2', гу - 2*х =5') х = 1+2*2ЛA/2) 1-2*2/чA/2)
Глава 2. Основы программы MATLAB 41 У = 7+4*2/чA/2) 7-4*2/чA/2) Эта система уравнений имеет два решения. Программа MATLAB выдает решение, выводя два значения х и два значения у для этих решений. Таким образом, первое решение состоит из первого значения х и первого значения у. Вы можете извлечь эти значения, введя в командную строку х A)иу A): » х A) ans = 1 + 2*2/чA/2) » У A) ans = 7+4*2/чA/2) Второе решение можно извлечь, введя х B) и у B). Обратите внимание, что в предыдущей команде solve мы назначили вывод в векторной форме [х# у]. Если вы используете команду solve в системе уравнений, не задавая вывод в векторной форме, в этом случае программа MATLAB не отображает автоматически значения решения: » sol = solve ('хА2 - у = 2', 'у - 2*х = 5Г) sol = х: [2x1 sym] у: [2x1 sym] Чтобы увидеть векторы значений х и у, введите sol. x и sol • у. Чтобы увидеть отдельные значения, введите sol.х A) и sol .у A), и т.п. ^ В этом примере вывод результата выполнения команды solve представляет собой структурный массив. Чтобы более подробно познакомиться с этим классом данных, смотрите раздел «Массивы ячеек и структур» в главе 6. Некоторые уравнения нельзя решить символически, и в таких случаях команда solve пытается найти числовой ответ. Например: » solve (' sin (х) = 2 - хг) ans = 1.1060601577062719106167372970301 Иногда бывает более одного решения, и вы можете не получить того, что ожидаете, например:
42 >> solve ('exp (-x) = sin (x) ' ) ans = MATLAB 2.0127756629315111633360706990971+2.703074511590962213931614804 4265*i Ответ представляет собой комплексное число. Хотя оно является правильным решением уравнения, существуют также решения, представленные вещественными числами. Графики функций ехр (-х) и sin (x) показаны на Рис. 2.3; каждая точка пересечения двух кривых представляет собой решение уравнения е"х - sin (х). Вы можете в числовой форме найти (приблизительно) решения, показанные на графике, с помощью команды f zero, которая ищет нулевое значение данной функции в пределах заданного значения х. Решение уравнения е~х ¦ sin (x) равно нулю в функции е"х - sin (x), поэтому, чтобы найти приблизительное решение при х = 0.5, введите следующее: >> h ¦ <?(х) ехр(-х) - sin(x); >> fzero (h, 0.5) ans = 0.5885 Замените значение 0.5 на 3 и найдите следующее решение, и так далее. ехр(-х) и sin(x) -0.5 Рис. 2.3. Две пересекающиеся кривые
Глава 2. Основы программы MATLAB 43 Графика В этом разделе вы познакомитесь с двумя основными командами черчения в программе MATLAB и научитесь использовать эти команды. Построение графиков командой ezplot Простейший способ построить график функции с одной переменной - использовать команду ezplot, которая может работать со строкой, символьным выражением или анонимной функцией, представляющих функцию для графического вывода. Например, чтобы построить график функции х2 + х + 1 в интервале от -2 до 2 (используя строчную форму команды ezplot), введите следующее: » ezplot ('хА2 + х + 1', [-2 2]) Чертеж графика будет отображен на экране в новом окне, озаглавленном «Figure 1». Используя символьное выражение, вы можете воспроизвести чертеж на Рис. 2.4, введя в командную строку следующее: >> syms х, ezplot ('xA2 + х + 1', [-2 2]) Наконец, вы можете использовать анонимную функцию в качестве аргумента для команды ezplot, например: » ezplot «? (х) х#А2 + х + 1, [-2 2]) %/ Графики могут отклоняться, если вы не обращаете внимания на оси. Например, ввод ezplot (хА2 + х + 3, [-2 2]) воспроизводит график, который выглядит идентичным предыдущему, за исключением того, что вертикальная ось имеет другие отметки (и программа MATLAB присваивает графику другое название). х2 + х + 1 0.5 1 1.5 -2 -1.5 -1 -0.5 X Рис, 2А. Парабола у « ж2 + ж - 1 на интервале [-2,2]
44 MATLAB Видоизменение графиков Вы можете изменять график различными способами. Вы можете изменить название графика на Рис. 2.4, введя следующее (в окне Command Window (Командное окно), а не в окне рисунка): » title 'A Parabola' Такое же изменение можно осуществить прямо в окне рисунка, выбрав команду Edit ¦ Axes Properties (Редактирование ¦ Свойства осей) в верхней части этого окна. (Просто введите новое название в поле, обозначенное Title (Название).) Вы можете добавить метку на вертикальной оси с помощью команды ylabel или изменить такую же метку на горизонтальной оси с помощью команды хlabel. Можно также изменить вертикальный и горизонтальный диапазоны графика с помощью команды axis. Например, чтобы ограничить вертикальный диапазон интервалом от 0 до 3, введите: » axis ([-1203]) Первые два числа представляют диапазон горизонтальной оси; в команду должны быть включены оба диапазона, даже если изменяется только один. Чтобы создать изображение квадрата графика, введите axis square; при этом шкалы будут одинаковыми на обеих осях, если диапазоны х и у имеют равную длину. Для диапазонов любой длины вы можете создать одинаковую шкалу на обеих осях, не изменяя изображение, вводом команды axis equal. Обычно эта команда расширяет один из диапазонов, если это необходимо. Однако, если вы нечаянно обрежете часть графика, эта утраченная часть не исчезнет из памяти программы MATLAB. Вы можете вновь настроить диапазоны с помощью команды axis или ввести команду axis tight, чтобы автоматически задать диапазоны, которые будут включать график полностью. Чтобы узнать о дополнительных возможностях, введите help axis. (He забудьте сначала ввести more on, если вы хотите прочитать сразу всю страницу.) Некоторые из этих изменений вы можете осуществить прямо в окне изображения, воспользовавшись открывающимся меню на панели инструментов этого окна. Наш опыт говорит, что делать это с помощью команд программы MATLAB в окне Command Window (Командное окно) будет более трудоемко, особенно если вы хотите сохранить ваши команды в М-файле (см. уроке 3), чтобы позже воссоздать тот же график. Чтобы закрыть изображение, ведите close или close all, или просто щелкните мышью на кнопке [х] в верхнем правом углу окна. °^ Чтобы познакомиться с другими способами видоизменения графиков, обратитесь к главе 5.
Глава 2. Основы программы MATLAB 45 Построение графиков командой plot Команда plot работает с векторами числовых данных. Синтаксис команды представляет собой: plot (X# Y), где X и Y являются векторами одинаковой длины. Например: » X = [1 2 3]; Y = [4 6 51; plot (X# Y) Рис. 2.5. Построение линейных сегментов •/ В этом случае мы отделили несколько команд в одной строке с помощью точки с запятой, вместо запятой. Обратите внимание, что вывод команд, предшествующих знаку точка с запятой, запрещается. Команда plot рассматривает вектора X и Y, как перечни координат последовательных точек на графике, и соединяет точки в виде линейных сегментов. Таким образом, на Рис. 2.5 показано, как программа MATLAB соединяет точки с координатами A, 4), B, 6) и C, 5). Чтобы начертить график функции х2 в интервале от -1 до 2, сначала требуется создать перечень X из значений х, а затем ввести plot (X# Х# А2). (Точка в данном выражении обязательна, так как Х.А2 представляет собой поэлементное возведение в квадрат вектора X, но не матричный квадрат.) Нам необходимо использовать достаточное количество значений х для уверенности в том, что результирующий график, нарисованный путем соединения точек, будет выглядеть нормально (плавная, а не ломаная линия). Мы используем приращение в размере 0.01. Таким образом, чтобы отобразить график параболы, введите: » X = -1:0.01:2; plot(X# X.A2)
46 MATLAB Результат отображен на Рис. 2.6. Обратите внимание, что мы использовали точку с запятой, чтобы запретить вывод вектора X из 301 элемента. -1 -0.5 0 0.5 1 1.5 Рис. 2.6. Построенная парабола °3> Более подробно графические команды программы MA TLAB рассматриваются в уроке 5. А пока удовлетворимся демонстрацией построения пары выражений на одном и том же графике. Построение нескольких кривых Каждый раз, когда вы выполняете команду построения (черчения), программа MATLAB стирает старый чертеж и рисует новый. Если вы хотите произвести наложение двух или более чертежей, используйте команду hold on. Эта команда дает программе MATLAB инструкцию - сохранять старые изображения и рисовать любые новые изображения поверх старых. Эта инструкция будет выполняться до тех пор, пока вы не введете команду hold off. Ниже приведен пример с использованием команды ezplot: » ezplot('exp(-x)', [0 10]) >> hold on » ezplot('sin(x)', [0 10]) >> hold off » title 'exp(-x) and sin(x)'
Глава 2. Основы программы MATLAB 47^ Результат показан на Рис. 2.3 ранее в этом уроке. Команды hold on и hold off работают со всеми графическими командами. С помощью команды plot вы можете сразу чертить несколько кривых. Например: » X = 0:0.01:10; plot (X, ехр(-Х), X, sin(X)) Обратите внимание, что вектор координат оси х должен задаваться один раз для каждой функции, которая будет выводиться в виде графика.
ГЛАВА 3. Взаимодействие с программой MATLAB В этом уроке мы рассмотрим эффективные действия, необходимые для работы с программой MATLAB, а также для подготовки и презентации результатов сессии этой программы. Здесь будут рассматриваться возможности интерфейса программы MATLAB и использование М-файлов. Мы познакомим вас с новой командой MATLAB 7, командой publish, с помощью которой осуществляется форматированный вывод. Мы также дадим вам несколько простых советов по отладке ваших М-файлов. Интерфейс программы MATLAB Начиная с версии 6, программа MATLAB имеет интерфейс, который называется Рабочий стол программы MATLAB (далее - Рабочий стол). В этот интерфейс входит окно Command Window (Командное окно), рассмотренное в главе 2. Рабочий стол По умолчанию Рабочий стол (Рис. 1.1 в главе 1) включает в себя четыре окна: окно Command Window (Командное окно) в правой части Рабочего стола, окна Current Directory (Текущий каталог) и Workspace (Рабочая область) в верхней левой части и окно Command History (История команд) в нижней левой части. Обратите внимание, что для переключения между окнами Current Directory (Текущий каталог) и Workspace (Рабочая область) имеются вкладки, повторяющие название окна. Вы можете управлять отображением окон с помощью меню Рабочего стола (в версии 6 меню View (Вид)), расположенного в верхней части Рабочего стола, кроме того, вы можете регулировать размеры окон путем перетаскивания границ окон с помощью мыши. Окно Command Window (Командное окно) представляет собой окно, в котором вы вводите команды и инструкции, заставляющие программу MATLAB вычислять, рисовать и выполнять множество других впечатляющих вещей, которые описываются в этой книге. Остальные окна мы рассмотрим в особом разделе далее в этом уроке. Рабочий стол включает в себя строку меню и панель инструментов. Панель инструментов содержит значки (ярлыки), предоставляющие доступ к некоторым элементам программы, которые вы можете выбрать через меню. Многие элементы меню имеют также клавиатурные комбинации, которые отображаются справа от пункта меню. Некоторые из этих клавиатурных комбинаций зависят от вашей операционной системы, в основном мы не будем их упоминать. Тем не менее, вы можете счесть эту возможность полезной и использовать клавиатурные комбинации в своей работе для вызова пунктов меню, которые вами наиболее часто применяются.
Глава 3. Взаимодействие с программой MATLAB 49^ Каждое окно на Рабочем столе содержит две маленькие кнопки в верхнем правом углу. Одна из них, имеющая вид [х], позволяет закрыть окно, а другая, в виде изогнутой стрелки, позволяет открепить окно от Рабочего стола (вернуть окно обратно на Рабочий стол вы можете, выбрав команду меню Desktop ¦ Dock (Рабочий стол ¦ Закрепить) на открепленном окне или щелкнув на изогнутой стрелке, расположенной в строке меню). %/ Хотя Рабочий стол предоставляет некоторые новые возможности и общий интерфейс для версий программы MATLAB под управлением операционных систем Windows и Unix, тем не менее, программа с открытым Рабочим столом может работать гораздо медленнее, чем базовый интерфейс окна Command Window (Командное окно), особенно на старых компьютерах. Чтобы работать в программе MATLAB со старым интерфейсом, необходимо запустить программу с помощью команды mat lab -nodesktop. Рабочая область В главе 2 вы-познакомились с командами clear и whos, которые можне-исполь- зовать для отслеживания переменных, заданных вами в течение сессии программы MATLAB. Все переменные находятся в области памяти компьютера, называемой «Рабочей областью». Полный перечень заданных переменных отображается в одноименном окне Workspace (Рабочая область). Отобразить это окно вы можете, введя команду workspace, или, при открытом Рабочем столе, щелкните мышью на вкладке Workspace (Рабочая область) в нижней части окна Current Directory (Текущий каталог). Окно Workspace (Рабочая область) содержит список текущих переменных и их размеры (но не значения переменных). Если вы дважды щелкнете мышью на переменной, значение переменной будет отображено в новом окне, называемом Array Editor (Редактор массива), которое вы можете использовать для редактирования отдельных элементов в векторах и матрицах. (Это окно можно также открыть, введя команду openvar и имя интересующей вас переменной.) Вы можете удалить переменную из «рабочей области», выделив ее в окне Workspace (Рабочая область) и выбрав команду меню Edit ¦ Delete (Редактирование ¦ Удалить). Если вам необходимо прервать сессию и вы не хотите впоследствии вычислять все повторно, то вы можете сохранить текущую «рабочую область» с помощью команды save. Например, после ввода команды save xnyfile будут сохранены значения всех заданных текущих переменных в файле с именем myfile.mat. Чтобы сохранить только значения переменных X и Y, введите следующее: >> save myfile X Y Когда вы начинаете новую сессию и желаете восстановить значения этих переменных, используйте команду load. Например, введение команды load myfile восстановит значения всех переменных, сохраненных в файле myfile.mat.
j№ MATLAB •/ По умолчанию переменные сохраняются в двоичном формате, который является обычным для программы MATLAB, но вы можете также сохранять и загружать данные (команды save и load) в текстовом формате ASCII. Чтобы узнать подробности, обратитесь к онлайновой справке для этих команд. Эта возможность может быть полезна для обмена данными с другими программами. Текущий каталог и путь поиска Новые файлы, которые вы создаете в программе MATLAB, будут храниться в вашем текущем каталоге. Имя этого каталога отображается на панели инструментов Рабочего стола, а файлы и подкаталоги, которые содержит текущий каталог, отображаются в окне Current Directory (Текущий каталог). Отобразить имя текущего каталога вы можете также с помощью команды pwd («print working directory» (Отобразить рабочий каталог)) в окне Command Window (Командное окно), и можете также получить список содержимого текущего каталога, введя команду dir или Is. •/ Термин «папка» в настоящее время употребляется более широко, чем «каталог»; для файловой системы компьютера между ними нет разницы. Мы будем использовать термин «каталог», поскольку программа MATLAB использует этот термин в своей документации. Однако в интерфейсе программы иногда используется и термин «папка», например, в столбце File Type (Тип файла) в окне Current Directory (Текущий каталог). У вас может возникнуть желание сменить текущий каталог по умолчанию, или вы захотите держать отдельные каталоги для различных проектов. Вы можете изменить текущий каталог в программе MATLAB, используя команду cd, окно Current Directory (Текущий каталог) или открывающийся список Current Directory (Текущий каталог) на панели инструментов Рабочего стола. Вы можете ввести имя каталога в это поле и нажать клавишу lEnterl. выбрать каталог, которым вы пользовались ранее, щелкнув мышью на кнопке со стрелкой в правой части поля, или выбрать каталог, щелкнув мышью на значке f —| Browse for folder (Обзор папок), расположенном справа от поля. Например, на компьютере под управлением операционной системы Windows текущим каталогом по умолчанию является подкаталог с именем work, расположенный в каталоге установки программы MATLAB; например, это может быть каталог C:\MATLAB7\work. Вы можете создать новый каталог, скажем, ProjectA, внутри него, введя команду xnkdir ProjectA. Вы можете также щелкнуть правой кнопкой мыши в окне Current Directory (Текущий каталог) и выбрать команду меню New ¦ Folder (Создать ¦ Папка) или щелкнуть мышью на значке |^'| New folder (Новая папка), расположенном на панели инструментов этого окна. Затем введите команду cd ProjectA или дважды щелкните на ней мышью в окне Current Directory (Текущий каталог), чтобы сделать этот каталог вашим текущим каталогом. После этого вы сможете работать с файлами данного каталога в текущей сессии программы MATLAB.
Глава 3. Взаимодействие с программой MATLAB Если вам необходима возможность чтения файлов из определенного каталога, то альтернативным способом сделать этот каталог текущим является добавление имени каталога к пути каталогов, которые программа MATLAB просматривает в поисках файлов. Текущий каталог и каталоги в заданном вами пути являются единственными объектами, в которых программа MATLAB ищет файлы, за исключением случая, когда вы введете имя каталога в качестве части имени файла (полный путь). Чтобы увидеть текущий путь, введите команду path. Чтобы добавить каталог C:\MATLAB7\work\ProjectA к вашему пути, введите следующее: » addpath C:\MATLAB7\work\ProjectA Обратите внимание, что программа MATLAB на вашем компьютере может быть установлена в каталоге с другим именем! В этом случае вам необходимо набрать наименование пути, соответствующего имени пути к программе для вашего компьютера! Например, это может быть D:\Programs\MATLAB71\work\ProjectA). При добавлении каталога к пути, файлы, которые содержатся в этом каталоге, остаются доступными для других операций в вашей сессии независимо от того, добавите ли вы позже другой каталог к пути или измените текущий каталог. Существенный недостаток этого подхода в том, что вам следует проявлять осторожность при присваивании файлам имен. Когда программа MATLAB производит поиск файлов, поиск считается завершенным, когда найден первый файл с корректным именем в списке пути, начиная с текущего каталога. Если вы используете одно и то же имя для различных файлов в различных каталогах пути, то могут возникнуть проблемы. Вы также можете управлять поисковым путем программы MATLAB с помощью инструмента Set Path (Установка пути). Чтобы открыть этот инструмент, введите команду editpath или pathtool, или выберите команду меню File ¦ Set Path... (Файл ¦ Установка пути). Инструмент Set Path (Установка пути) состоит из панели со списком каталогов текущего пути и нескольких кнопок, которые позволяют добавлять, удалять и сортировать каталоги в вашем пути. |/ Если у вас установлено много панелей инструментов, поиск путей может быть медленным, особенно с применением команды lookfor. Один из способов ускорить процесс - удалить панели инструментов, которые вы в данный момент не используете. ¦5* Изменения, которые вы осуществляете с текущим каталогом и путем, не сохраняются в программе MATLAB от сессии к сессии. В конце раздела «М-файлы - сценарии» далее в этом уроке мы покажем, как автоматически изменять эти и другие элементы каждый раз при запуске программы MA TLAB. Окно Command History (История команд) Окно Command History (История команд) содержит текущую историю команд, которые вы вводите в окне Command Window (Командное окно). Это полезно в двух ситуациях. Во-первых, это позволяет вам с одного взгляда увидеть запись
J52 MATLAB команд, которые вы ввели ранее. Во-вторых, это может сберечь вам время, затрачиваемое на ввод. Если вы щелкнете мышью на одной из записей (команд) в окне Command History (История команд), эта команда будет немедленно выполнена в окне Command Window (Командное окно). Однако зачастую вам понадобится редактировать предыдущую команду перед ее выполнением. Если вы щелкнете правой кнопкой мыши на записи команды в окне Command History (История команд), то команда будет выделена и на экране отобразится меню параметров. Вы можете выбрать команду Сору (Копировать), затем щелкнуть правой кнопкой мыши в окне Command Window (Командное окно) и выбрать команду Paste (Вставить), после чего выбранная вами команда будет отображена в командной строке и будет готова для редактирования. Подобно тому, как это описано в разделе «Разрешение проблем» в предыдущей главе, вы можете также использовать клавиши со стрелками [TJ и JJJ в окне Command Window (Командное окно), чтобы прокручивать список команд, которые вы недавно применяли. Когда вы найдете нужную строку команды, можно использовать клавиши Ij^j и ?j, чтобы перемещаться по командной строке, удаляя символы или вставляя новые; затем следует нажать клавишу l:Enterl. чтобы заставить программу MATLAB выполнить отредактированную команду. Например, вам может понадобиться вычислить с точностью до 15 знака значения sin@.1)/0.1, sin(O.Ol)/0.01 и sin@ .001) /0.001. Ниже представлен первый вариант решения вместе с ответом, который программа MATLAB отображает в окне Command Window (Командное окно): » х = [0.1, 0.01, 0.001]; >> у = sin(x)/x У = 0.9984 Результат неожиданный. Отображается только одно число вместо трех. Не забывайте, чтобы разделить два вектора поэлементно, вам необходимо ввести символы «./», а не просто символ «/». (Введение только символа «/» решает уравнение у*х = sin(x) для у методом наименьших квадратов; для получения более полной информации введите help slash.) Другая проблема состоит в том, что отображаются не 15, а всего лишь 5 знаков. Чтобы решить эти проблемы, введите сначала команду format long. Затем дважды нажмите клавишу [TJ, чтобы вновь отобразить команду, задающую переменную у, и дважды нажмите на клавишу ?J, чтобы поместить текстовый курсор между символами «)» и «/». Наконец, введите символ точки «.» и нажмите клавишу Fnterl: >> у = sin(x)./x У = 0.99833416646828 0.99998333341667 0.99999983333334
Глава 3. Взаимодействие с программой MATLAB 53^ М-файлы М-файлы позволяют сохранять множество команд программы MATLAB в одном файле, а затем запускать их одной командой или с использованием мыши. Вы можете достаточно легко и правильно решать простые задачи с первой попытки, однако более сложные задачи обычно решаются методом проб и ошибок - запуском, редактированием и перезапуском серий команд несколько раз подряд. В то время как окно Command History (История команд) может быть полезно на протяжении первых стадий этого процесса, в конечном счете вы убедитесь, что гораздо более эффективным будет использование М-файлов. М-файлы также позволяют использовать ваше решение задачи совместно с другими пользователями программы MATLAB и форматировать ваши результаты для прочтения их другими. Существует два различных типа М-файлов: М-файлы-сценарии и М-файлы-функции. Мы продемонстрируем использование обоих типов М-файлов подобно тому, как представляем различные решения задач, рассмотренные выше. М-файлы представляют собой обыкновенные текстовые файлы, содержащие команды программы MATLAB. Вы можете создавать и модифицировать эти файлы, используя любой текстовый редактор или текстовый процессор, который способен сохранять файлы в виде простого текста в формате ASCII. (Это такие редакторы, как Notepad и WordPad в системе Windows, и emacs и vi - в системах UNIX.) Для большего удобства вы можете использовать встроенный модуль Editor (Редактор), который можно запустить с помощью команды edit, сам по себе (для редактирования нового файла), или выбрав имя существующего М-файла в текущем каталоге. Для запуска модуля Editor (Редактор) вы можете также использовать меню File (Файл) или два крайних слева значка на панели инструментов, как для создания нового М-файла, так и для открытия уже существующего. Двойной щелчок мышью на М-файле в окне Current Directory (Текущий каталог) также откроет выбранный файл в модуле Editor (Редактор). М-файлы-сценарии М-файл-сценарий содержит последовательность команд программы MATLAB для запуска в определенном порядке. Сейчас мы покажем, как сконструировать М-файл- сценарий для решения математической задачи, рассмотренной ранее. Создайте файл, содержащий следующие строки: format long х = [0.1# 0.01, 0.001]; у = sin(x)./х Предположим, что вы сохранили этот файл под именем taski.m в вашем текущем каталоге или в каком-либо каталоге вашего пути. Вы можете присваивать файлу имя любым способом (в вашей операционной системе могут быть свои особенности), но расширение .т является обязательным.
^4 MATLAB Вы можете заставить программу MATLAB запустить (или выполнить) этот сценарий, введя команду taski в окне Command Window (Командное окно). (Вам не следует вводить здесь расширение .т; программа MATLAB автоматически добавляет расширение, когда производит поиск файлов.) Вывод результатов (но не команд, с помощью которых вычисляется результат) будет отображен в окне Command Window (Командное окно). Теперь последовательность команд может быть легко изменена путем модификации М-файла taski .m. Например, если вы хотите вычислить также sin @.0 0 01)/ 0 • 0 0 01, вы можете модифицировать М-файл: format long х = [0.1, 0.01, 0.001, 0.0001]; у = sin(x)./x а затем запустить модифицированный сценарий, снова введя команду taski. Но сначала убедитесь, что сохранили свои изменения в файле taski; в противном случае программа MATLAB не распознает эти изменения. •/ Некоторые переменные, задаваемые при запуске М-файлов-сценариев, будут сохраняться, как если бы вы ввели эти переменные в окне Command Window (Командное окно) напрямую. Например, программа, рассмотренная выше, послужит причиной того, что в будущем все числовые результаты будут отображаться с точностью до 15 знака. Чтобы вернуться к формату с 5 знаками, следует ввести команду format short. Добавление комментариев М-файлы рекомендуется снабжать комментариями. Эти комментарии могут содержать объяснения, что конкретно делается в процессе вычисления, или могут интерпретировать результаты вычисления. В программе MATLAB комментарий начинается со знака процента «%»; строка после этого знака не выполняется программой. (В модуле Editor (Редактор) комментарии выделяются зеленым цветом, чтобы помочь вам отличить их от команд, которые имеют черный цвет.) Ниже показана новая версия файла taski.m с добавлением некоторых комментариев: format long % turn on 15 digit display x = [0.1, 0.01, 0.001]; у = sin(x)./x % These values illustrate the fact that the limit of % sin(x)/x as x approaches 0 is 1. Обратите внимание, что многострочный комментарий требует введения знака процента в начале каждой строки.
Глава 3. Взаимодействие с программой MATLAB 55^ Режим ячейки Новые возможности программы MATLAB 7 позволяют разделять М-файл - сценарий на части (элементы), которые называются ячейками. Это особенно полезно, если ваш М-файл длинный или если вы собираетесь его публиковать (последняя тема рассматривается в разделе «Публикация М-файлов»). Чтобы запустить новую ячейку, вставьте строку комментария (которая послужит в качестве заголовка ячейки), начав эту строку двумя знаками процента %%. Если вы откроете М-файл в модуле Editor (Редактор) и выберете команду меню Cell ¦ Enable Cell Mode (Ячейка ¦ Включить режим ячейки), в этом случае под первой панелью инструментов будет отображена вторая панель. Когда вы щелкнете мышью на какой-нибудь строке в М-файле, ячейка, которой принадлежит эта строка, будет выделена бледно-желтым цветом. Вы можете произвести вычисление этой ячейки, выбрав команду меню Cell ¦ Evaluate Current Cell (Ячейка ¦ Вычислить текущую ячейку) или щелкнув мышью на значке | й[ Evaluate cell (Вычислить ячейку). Это может быть весьма полезным, если вы внесли изменения только в одну ячейку и не хотите снова полностью запускать весь сценарий. Имеются также элемент меню и значок ^ для выполнения операции Evaluate cell and advance (Вычислить ячейку и далее). Так как вы включили режим ячейки, вы можете также создать дополнительные ячейки, выбрав команду меню Cell ¦ Insert Cell Divider (Ячейка ¦ Вставить разделитель ячеек) или щелкнув мышью на значке %+ . Инициализация М-файлов-сиенариев Чтобы результаты М-файла-сценария были воспроизводимы, сценарий должен быть автономным, независимым от других переменных, которые вы можете задать где-либо в течение сессии программы MATLAB, оставшейся от предыдущих вычислений графика должна быть также удалена. Например, если вы зададите переменную с именем sin в окне Command Window (Командное окно), а затем запустите сценарий taski.m, вы получите сообщение об ошибке, так как в текущий момент sin будет представлять переменную, а не обычную встроенную функцию. Помня об этом, вы можете ввести строку clear all в начало М-файла- сценария, чтобы быть уверенным, что предыдущие настройки переменных не повлияют на результаты. Вы можете также ввести строку close all в начале М-файла-сценария, создающего графику, чтобы закрыть все окна изображений и начать «с чистого листа». Как отмечалось ранее, команды в М-файле-сценарии не будут автоматически отображаться в окне Command Window (Командное окно). Если вы хотите, чтобы команды отображались вместе с результатами, добавьте команду echo on в начало сценария (нелишним будет также добавить команду echo off в конец сценария). Тогда и любые комментарии в М-файле будут также отражены. При запуске длинного М-файла-сценария подобная операция полезна, чтобы отслеживать: какой вывод какому вводу соответствует.
j>6 MATLAB Ниже представлена версия файла taski.m с более подробными комментариями, в которой отображается как ввод, так и вывод. clear all % remove old variable definitions echo on % display the input in the command window format long % turn on 15 digit display x = [0.1, 0.01, 0.001]; % define the x values у = sin(x)./x % compute the desired quotients % These values illustrate the fact that the limit of % sin(x)/x as x approaches 0 is equal to 1. echo off Автозагрузка М-файда При запуске программа MATLAB производит поиск в пути по умолчанию на предмет М-файла-сценария с именем startup.m. Если вы создадите такой файл, то команды, которые он содержит, будут запускаться каждый раз, когда запускается программа MATLAB. Вы можете использовать этот файл для сохранения настроек, которые переходят из одной сессии в другую, например, изменения текущего каталога или пути. (Кроме команд cd и addpath, рассмотренных выше, вы можете использовать команду rmpath для удаления каталогов из пути.) М-файлы-функиии М-файлы-функции, в отличие от М-файлов-сценариев, позволяют задавать значения ввода, когда вы запускаете такие М-файлы из командной строки MATLAB или из другого М-файла. Как упоминалось в предыдущей главе, вы можете также использовать синтаксис анонимной функции (@) (отсутствующий в программе MATLAB 6 и более ранних версиях) или команду inline для задания своих собственных функций в командной строке. Однако эти методы обеспечивают задание функции только в одной строке. Таким образом, М-файлы необходимы для задания более сложных функций. Подобно М-файлу-сценарию, М-файл-функция представляет собой файл с простым текстом, который может находиться в вашем текущем каталоге или где-либо в вашем пути MATLAB. Давайте вернемся к рассмотренной выше задаче, в которой мы вычисляли некоторые значения sin(x) /х, где х = 10~ь при некоторых значениях Ь. Кроме того, предположим, что вы хотите найти наименьшее значение Ь, для которого sinA0"b)/ A0~ь)# и чтобы результат был равен 1 с точностью до 15 знаков.
Глава 3. Взаимодействие с программой MATLAB 57^ Ниже представлен М-файл-функция с именем sinelimit.m, составленный с целью выяснения этого вопроса: function у = sinelimit (с) % SINELIMIT computes sin (x)/x for x = 10A(-b) % where b = 1, ...# с. Format long b = l:c; x = 10.A(-b); у = (sin (x)./x) ' ; Первая строка файла начинается со слова function, которое идентифицирует файл как М-файл-функцию. (В модуле Editor (Редактор) это зарезервированное слово выделяется синим цветом.) Первая строка М-файла задает имя функции и описывает как входящие аргументы (или параметры), так и исходящие значения. В этом примере функция называется sinelimit. Имя файла (за исключением расширения .т) и имя функции должны совпадать. Когда вы создаете этот новый М-файл-функцию в безымянном окне редактора и выбираете команду Save (Сохранить), модуль Editor (Редактор) сам присваивает файлу имя sinelimit.m. Функция в нашем примере имеет для ввода один элемент, который внутри М-файла обозначен как с. В качестве результата возвращается тоже один элемент - значение у, появляющееся в конце выполнения функции. Неплохой практикой является снабжать первую строку М-файла-функции одной или более строками комментариев, разъясняющих, что делает М-файл. При этом команда help автоматически извлечет данную информацию. Например: >> help sinelimit SINELIMIT computes sin (x)/x for x = lO^-b) where b = 1, . . . , с. Остальные строки М-файла определяют функцию. В данном примере b задается в качестве строчного вектора, состоящего из целых чисел от 1 до с, затем х вычисляется из Ь, и, наконец, у определяется из х. ^ Переменные, которые используются в М-файле-функции, такие как b, x и у в файле sinelimit.m, являются локальными переменными. Это означает, что, в отличие от переменных, заданных в М-файле-сценарии, эти переменные не связаны с любыми другими переменными с такими же именами, которые вы могли использовать в окне Command Window (Командное окно). Программа MATLAB не запоминает значения этих переменных после того, как М-файл-функция будет выполнен. Для получения более полных сведений обратитесь к разделу «Переменные в М- файлах-функциях» в главе 4.
5* MATLAB Обратите внимание, что строки, задающие b, x и у, заканчивается точкой с запятой. Использование точки с запятой в конце строк определяет отсутствие вывода результатов для этих строк, то есть результат работы этих строк не будет отображаться в окне Command Window (Командное окно). Несмотря на то, что отображение результатов промежуточных вычислений может быть полезным для отладки, в основном вам следует пресекать весь вывод в М-файле-функции. Ниже представлен пример, показывающий, как используется функция sinelimit: » sinelimit E) ans = 0.99833416646828 0.99998333341667 0.99999983333334 0.99999999833333 0.99999999998333 Ни одно из значений b от первого до пятого не приводит к желаемому результату, 1 с точностью до 15 знака. Судя по выведенному результату, можно надеяться найти ответ на ранее поставленный вопрос, введя команду sinelimit A0). Попробуйте! Циклы Цикл предполагает наличие условия, что команда или группа команд должны повторяться несколько раз. Самый простой способ создать цикл - это использовать выражение for. Ниже показан простой пример, где вычисляется и отображается 10! в ю * 9 * 8 ... * 2 * 1. f - 1# for n ¦ 2:10 f ¦ f*n; end f Цикл начинается с выражения for и заканчивается выражением end. Команда между этими выражениями выполняется в целом девять раз, по одному разу для каждого значения п от 2 до 10. Для прерывания промежуточного вывода внутри цикла мы использовали точку с запятой. Чтобы увидеть конечный результат, необходимо ввести f после завершения цикла. Если не использовать точку с запятой, программа MATLAB будет отображать каждое промежуточное значение 2!, 31, и т.д.
Глава 3. Взаимодействие с программой MATLAB 59^ В модуле Editor (Редактор) команды for и end автоматически выделяются синим цветом. Это придает лучшую читабельность, если вы вставляете между ними команды (как мы это сделали); модуль Editor (Редактор) делает это автоматически. Если вы введете for в окне Command Window (Командное окно), программа MATLAB не выдаст новое приглашение командной строки >>, пока вы не введете команду end, при которой программа MATLAB выполнит полный цикл и отобразит новую командную строку. •/ Если вы используете цикл в М-файле-сценарии с эффектом отображения echo on, то команды будут отражаться каждый раз во всем цикле. Вы можете предотвратить это, вставив команду echo off прямо перед выражением end и команду echo on сразу после него; тогда каждая команда в цикле будет отражена один раз (кроме end). Представление результатов Иногда вам может понадобиться показать кому-нибудь результаты созданного М-файла-сценария. Для лучшего представления вы можете импортировать свои результаты в другую программу, например, в текстовый процессор, применить команду publish для преобразования своих результатов в форму HTML, или (на компьютере под управлением Windows) использовать М-книгу. Для более оперативного совместного использования ваших результатов вы можете дать кому-либо свой М- файл, будучи уверенным, что это лицо располагает копией программы MATLAB, в которой может запустить его, или можете предоставить полученные результаты в форме файла-дневника. Сейчас мы рассмотрим эти различные способы. •/ Вы можете значительно увеличить читабельность своего М-файла, включив в текст подробные комментарии. Комментарии должны объяснять, что конкретно вычисляется, чтобы читатель мог понять ваши процедуры и стратегию. После завершения вычислений вы можете также добавить комментарии для интерпретации результатов. Публикация М-файлов В состав программы MATLAB 7 входит очень удобная команда - publish, которая предназначена для преобразования М-файла-сценария в документ, предназначенный для чтения. Эту возможность следует использовать в комбинации с ячейками (см. раздел «Режим ячейки» выше). Формат вывода по умолчанию, который, по нашему мнению, работает лучше всего, это HTML (то есть web-страница), но вы можете также осуществить публикацию в документ программы Word или в презентацию в программе PowerPoint (на компьютере под управлением Windows) или в документ LATEX (издательская программа в среде UNIX - прим. пер.). Если в модуле Editor (Редактор) включен режим ячейки, вы можете также использовать кнопку а Publish to HTML (Опубликовать в HTML), расположенный на панели инструментов Cell (Ячейка) (которая появляется под стандартной панелью инструментов Editor (Редактор)).
J>0 MATLAB Публикация М-файла воспроизводит М-файл со всем текстом и графикой. Каждая ячейка М-файла отображается в виде отдельного раздела, под заголовком, взятым из строки, начинающейся с двух знаков процента. Любые строки комментария, которые следуют сразу за этой строкой, отображаются при выводе в виде форматированного текста; это обеспечивается тем, что строка начинается со знака процента с пробелом. Кроме того, в этом тексте отсутствуют какие-либо пустые промежуточные строки. (Вы можете выбирать из нескольких форматов, например, списки-бюллетени, с помощью команды меню Cell ¦ Insert Text Markup ¦ BuMeted List (Ячейка ¦ Вставить текстовую разметку ¦ Список-бюллетень) в модуле Editor (Редактор).) Далее все строки ввода программы MATLAB и любые оставшиеся комментарии в ячейке воспроизводятся без какого-либо форматирования, как обычный текст и графика. (Не обязательно использовать команду echo при публикации М-файла; ввод и комментарии всегда отображаются в публикуемом документе.) %/ Строка, начинающаяся с двойного знака процента, но не имеющая текста, запускает новую ячейку, но не создает озаглавленный раздел в публикуемом материале. В этом случае запуск новой ячейки позволяет вам вставлять форматированный текст, в котором рассматривается материал предыдущей ячейки, не запуская новую секцию. Что более важно, это позволяет вам отображать информацию ввода и вывода близко друг к другу в разделе, где много строк ввода. Если вы не разобьете такой раздел на более мелкие ячейки, то вся информация ввода в нем будет отображаться перед всей информацией вывода, что создаст путаницу при соотнесении вывода с вводом. Ниже показана другая версия рассмотренного выше М-файла-сценария taski.m, который подготовлен для публикации. %% Sample Script M-file % This script computes sin(x)/x for x = 0.1, 0.01# 0.001. clear all % remove all variable definitions format long % turn on 15 digit display x = [0.1, 0.01, 0.001]; % define the x values у = sin(x)./x % compute the desired quotients % These values illustrate the fact that the limit of % sin(x)/x as x approaches 0 is equal to 1. Если ваш М-файл помещает два последовательных изображения в одно и то же окно изображения, тогда только последнее изображение будет прорисовано в публикуемом документе, хотя изображения появляются в различных ячейках. Вам следует или запускать новую ячейку каждый раз при создании нового изображения, или использовать команду figure, чтобы открывать отдельные окна для каждого изображения, производимого данной ячейкой.
Глава 3. Взаимодействие с программой MATLAB и^3 Для получения более полных сведений о публикации обратитесь к главе 7. Смотрите главу 5, чтобы более подробно познакомиться с окнами изображения. Файлы-дневники В то время как команда publish доступна только при запущенной программе MATLAB 7, все версии этой программы имеют более простую команду diary, которая сохраняет в файл из сессии весь текстовый вывод (а при использовании команды echo on и ввод тоже). Ниже показан способ использования команды diary для автоматического сохранения текстового ввода и вывода из М-файла- сценария в файл при каждом его запуске. В начале М-файла, например taski.m, вы можете включить команды: delete taskl.txt diary taskl.txt echo on Тогда М-файл - сценарий должен заканчиваться командами: echo off diary off Первая команда diary приводит к тому, что весь последующий ввод и вывод в окне Command Window (Командное окно) копируется в заданный файл - в данном случае - файл taski .txt. Файл-дневник taski .txt представляет собой простой текстовый файл, который пригоден для распечатки или импортирования в другую программу. Используя команду delete в начале М-файла, вы подтверждаете, что в файле содержится только информация вывода из самого недавнего запуска сценария. Если вы пропустите команду delete, тогда команда diary добавит новую информацию вывода в конец существующего файла и файл taskl.txt при этом будет заканчиваться результатами нескольких запусков М-файла. (Ввод команды delete в сценарий приведет к появлению безвредного предупреждающего сообщения о несуществующем файле, когда вы в первый раз запустите сценарий.) Также в файле-дневнике может появиться посторонняя информация вывода, если вы введете клавиатурное сочетание II ctrl Н[С|. чтобы остановить сценарий, содержащий команду diary. В этом случае вам следует ввести команду diary of f в окне Command Window (Командное окно) прежде чем продолжать. Интерактивные М-файлы Если вы хотите, чтобы кто-нибудь другой запускал ваши М-файлы-сценарии и просматривал результаты, в этом случае полезно применять команду pause для остановки выполнения в различных точках: после каждого воспроизведенного графика, после важных комментариев и после критических мест, где ваш сценарий генерирует числовой вывод. Каждый раз, когда программа MATLAB встречает
62 MATLAB команду pause, то, прежде чем продолжить, программа ожидает, когда пользователь нажмет клавишу. Конечно, если получатель вашего М-файла не знаком с командой pause, тогда вам следует включить дополнительные указания в таких точках; например, с помощью команды echo on вы могли бы ввести: Pause % Нажмите любую клавишу для продолжения • •. Если не применять команду echo on, тогда вы можете использовать команду disp, чтобы отобразить сообщение перед паузой. Другой полезной командой является команда input, которая отображает сообщение и ожидает от пользователя введения числа или другого выражения программы MATLAB; для получения более подробной информации обратитесь к онлайновой справке. |/ Эти интерактивные команды могут порядком надоедать, если вы, например, хотите опубликовать М-файл. Если ваш получатель знаком с режимом ячейки в модуле Editor (Редактор), тогда альтернативным вариантом использования команды pause будет разделение М-файла на ячейки, при котором ваш получатель будет запускать в файле одну ячейку за раз. |®> Программа MATLAB располагает также командами и инструментами для разработки графического интерфейса пользователя (GUI); см. главу 9. Эта возможность позволяет вашему получателю работать с М-файлом в отдельном окне, специально созданном вами, а не в окне Command Window (Командное окно). Продолжение на следующей строке длинных строк при вводе и выводе Иногда вам требуется ввести в окне Command Window (Командное окно) или в М-файле команду, которая слишком длинна, чтобы уместиться на одной строке. В этом случае при приближении к концу строки вы можете ввести ... (три последовательные точки), затем нажать клавишу llEnterl и продолжить ввод команды на следующей строке. Если вы сделаете это в окне Command Window (Командное окно), то не увидите на новой строке приглашение командной строки. С^^~^ Числовой вывод форматируется программой MATLAB так, чтобы подходить к вашему экрану, но символьные выражения обычно отображаются в одной строке, независимо от того, насколько они длинны. Если s является символьным выражением, тогда при введении pretty (s) это выражение будет отображаться в формате, удобном для распечатки, который использует на экране несколько строк, имитируя вычисления на бумаге. При этом результаты зачастую читаются гораздо легче, чем в формате по умолчанию. Важной функцией команды pretty является то, что эта команда продолжает на следующей строке длинные выражения, чтобы подогнать их к полю ввода (шириной в 80 символов) стандартного окна. Если ваша информация вывода настолько длинна, что выходит за правый край рабочего окна, она может быть усечена при распечатке, поэтому следует использовать команду pretty, чтобы вся информация вывода была видна.
Глава 3. Взаимодействие с программой MATLAB 63^ Распечатка и сохранение графики Как упоминалось в главах 1 и 2, графика отображается в отдельном окне изображения. Вы можете сохранить текущий отображенный график, выбрав команду меню File ¦ Save As... (Файл ¦ Сохранить как...) в окне изображения. Формат файла по умолчанию (.fig) является специальным форматом программы MATLAB и не распознается большинством других программ; однако для сохранения доступны и многие другие графические форматы. Вы можете также распечатать текущее изображение, выбрав команду меню File ¦ Print... (Файл ¦ Печать...), или можете ввести команду print, которая выведет изображение в текущем окне на печать, используя принтер по умолчанию. Так как вы не собираетесь распечатывать изображение каждый раз, когда запускаете сценарий, то не следует включать команду print в М-файл. Вместо этого лучше использовать форму данной команды, которая посылает информацию вывода в файл. Это также позволяет присвоить информативные заголовки вашим изображениям. Например: Close all % remove old figure windows % Graph sin (x) from 0 to 2*pi: x = 2*pi*@:0.01:l); plot (x, sin(x)) title ('Figure A: Sine Curve') % title the figure print -deps figureA % store the graph in figureA.eps Форма команды print, использованная в этом сценарии, приводит к тому, что текущее изображение записывается в формате EPS - Encapsulated PostScript ® в файл с именем figureA.eps в текущем каталоге. Этот файл можно распечатать позже (на принтере PostScript) или можно импортировать в другую программу, которая может считывать формат PostScript. Если вы собираетесь вставлять графику программы MATLAB в web-страницу, лучше сохранить изображение в файле формата .png с помощью команды print -dpng. (Вы можете также выбрать команду меню File ¦ Save As.» (Файл ¦ Сохранить как...) в окне изображения и в открывающемся списке Save as type (Тип файла) выбрать Portable Network Graphics file (*.png) (Переносимый сетевой графический файл).) Чтобы узнать о других доступных форматах, воспользуйтесь онлайновой справкой для команды print. В качестве последнего примера по работе с графикой рассмотрим задачу по графическому представлению функций sin(x), sinBx) и sinCx) в одной системе координат. Это типичный пример; нам часто приходится чертить несколько похожих кривых, уравнения которых зависят от параметра. Ниже показано решение задачи с помощью М-файла-сценария: х = 2*pi*@:0.01:1); % define the x values
MATLAB figure hold on % open a new figure window with overlay % Run a loop to plot three sine curves: for с = 1:3 plot (x# sin(c*x)) end hold off, axis([0# 2*pi, -1, 1]) % adjust the x axis title('Several Sine Curves') % title the figure Результат показан на рисунке (Рис. 3.1). Синусоидальные кривые Рис. 3.1. Синусоидальные кривые Давайте проанализируем это решение. Мы начинаем с определения координатной сетки из 101 равномерно расположенного значения от 0 до 2тт. Затем команда figure открывает новое окно изображения, а команда hold on дает программе MATLAB инструкцию, что мы хотим начертить несколько кривых на одной координатной сетке. Чтобы не вводить три раза команду plot, мы задаем цикл командой for, описанной выше. Затем вводим команду hold off, чтобы вывести окно изображения, придаем графику более привлекательный вид, изменяя диапазон горизонтальной оси, выбираемый программой MATLAB, на реальный диапазон х, и с помощью команды title присваиваем изображению заголовок. М-книги Другим подходящим способом представления информации вывода программы MATLAB без первоначального создания М-файла является документ программы Microsoft Word, включающий текст, команды программы MATLAB и графику. Это дает большие возможности управления форматированием, чем команда publish.
Глава 3. Взаимодействие с программой MATLAB 65^ Самый простой способ - это подготовить документ Word с объясняющими комментариями и вставить команды программы MATLAB (вы можете сделать это другим шрифтом), или включить в документ ваши М-файлы с помощью команды меню Insert ¦ File (Вставка ¦ Файл) в программе Word. Можно также вставить графику, выбрав команду меню Insert ¦ Picture ¦ From File (Вставка ¦ Рисунок ¦ Из файла) в этой же программе. Но прежде вам следует сохранить графику в одном из общеупотребительных форматов, таких как png, tiff или eps. Более простым способом является активация М-книг на вашем компьютере. М-книга представляет собой документ Word со встроенным исполняемым кодом программы MATLAB (который запускается как макрос посредством языка Visual Basic). Чтобы запустить М-книгу, вы можете ввести команду notebook в окне Command Window (Командное окно), или можете запустить программу Word и, выбрав команду меню File ¦ New (Файл ¦ Создать), выбрать элемент m-book (м- книга) в качестве шаблона документа. Если файл m-book.dot отсутствует на вашем компьютере, вам сначала необходимо активировать режим M-book (М-книга). Для этого введите >> notebook -setup в окно Command Window (Командное окно) программы MATLAB и следуйте инструкциям. Компьютер сделает запрос о версии программы Word, которую вы используете, и, возможно, о местоположении некоторых ассоциированных файлов. •/ В системах Windows XP, 2000 и NT на экран будет выведено сообщение об ошибке, если вы запустите команду notebook -setup под учетной записью без прав администратора. Однако шаблон m-book.dot будет все же скопирован в папку шаблонов программы Word. Затем вам требуется открыть М-книгу в программе Word, хотя запуск команды notebook в программе MATLAB не будет работать. Чтобы полностью активировать М-книги, вы должны получить права администратора для запуска команды notebook -setup и, возможно, перезаписать местоположение шаблона по умолчанию, чтобы назначить папку, к которой у вас есть доступ. Шаблон m-book.dot также можно скопировать и вручную в ту папку на вашем компьютере, где хранятся шаблоны для программы Word, из папки notebook\pc\ каталога, в который установлена программа MATLAB, например, C:\MATLAB71\notebook\pc (Прим. редактора). ^ Для корректного запуска М-книг вы должны включить выполнение необходимых макросов в программе Word. Самый безопасный способ сделать это - посмотреть, получите ли вы диалог с предупреждением о безопасности при открытии М-книги, и если получите, то выберите Always trust macros from this source (Всегда разрешать макросы из этого источника). Это сохранит вашу безопасность на уровне high (Высокий) для других макросов. С другой стороны, вы можете установить ваш уровень безопасности на medium (Средний) для всех макросов в диалоге, который будет отображен, если вы выберете команду меню Tools ¦ Macros ¦ Security... (Инструменты ¦ Макросы ¦ Безопасность...) в программе Word. 3-1605
66 MATLAB При успешном запуске М-книги, она будет работать так же, как и любой другой документ программы Word, за исключением меню Notebook (Книга) в верхней части. Если вы введете команду MATLAB и нажмете сочетание клавиш 11 Ctrl I+Fnterl или выделите команду мышью и выберете команду меню Notebook ¦ Evaluate Cell (Книга ¦ Вычислить ячейку), программа MATLAB выполнит команду и отправит результат обратно в программу Word. Для большей читабельности программа Word отображает «ячейки ввода» (ввод в программе MATLAB) полужирным шрифтом Courier зеленого цвета, а «ячейки вывода» (вывод в программе MATLAB) - тем же шрифтом, но синего цвета. Программа содержит параметр (вы можете его регулировать с помощью команды меню Notebook ¦ Notebook Options (Книга ¦ Параметры книги)), который заставляет отображаться окна изображений либо отдельно, либо в М-книге, либо обоими способами. С одной стороны, М-книги работают подобно М-файлам; вы можете их модифицировать и запускать снова и снова. Если вы обнаружите ошибку во введенной команде или захотите изменить команду, вы можете просто вернуться назад к требуемой ячейке ввода, изменить содержимое, а затем снова произвести вычисление. Старый результат вывода будет заменен новым. Однако не забывайте, что результаты вывода будут отражаться в порядке, в котором вы вычисляете ячейки, а не в том порядке, в котором они отображаются в М-книге. При подготовке окончательной версии вашего документа вам следует перезапустить всю М-книгу с помощью команды меню Notebook ¦ Evaluate M-book (Книга ¦ Вычисление М-книги) и убедиться, что команды приводят к желаемому результату, когда запускаются по порядку. Точная настройка М-файлов М-файлы - сценарии позволяют вам совершенствовать свою стратегию решения задачи без необходимости запускать ее каждый раз с нуля. Однако отладка длинных М-файлов может занять много времени. Ниже представлено несколько основных советов для диагностики ошибок (и их предотвращения при первом использовании). ^ Мы рассмотрим возможности модуля Editor (Редактор) и дополнительные отладочные команды программы MATLAB в разделе «Отладка» главы 6 и разделе «Методики отладки» главы 11. • Используйте команду publish с частыми разделителями ячеек, или команду echo on в начале М-файла, чтобы можно было видеть как «причину», так и «следствие». • Используйте режим ячейки в модуле Editor (Редактор) и достаточно свободно применяйте команду pause, чтобы видеть результаты только одной части (ячейки) М-файла. • Используйте точку с запятой для блокирования нежелательного вывода, особенно для длинных векторов и массивов.
Глава 3. Взаимодействие с программой MATLAB 67^ • Если вы создаете графику с помощью команды hold on, не забывайте вводить hold off перед запуском нового изображения, чтобы следующее изображение не смешивалось с предыдущим. • Также, при запуске нового изображения вставляйте разделитель ячеек или команду pause или используйте команду figure для открытия нового окна, чтобы следующая графическая команда не стирала текущую до того, как вы ее увидите. • Не включайте в свои М-файлы простую команду print. Вместо этого выводите на печать в файл. • Команда keyboard похожа на команду pause, но более полезна для отладки. Если ваш М-файл содержит команду keyboard, то программа MATLAB прерывает на этой команде выполнение вашего сценария и на экране появляется новое приглашение командной строки, со стоящей перед ним буквой К. В этой точке вы можете ввести любую обычную команду программы MATLAB. Это полезно, если вы хотите проверить или переназначить новые переменные в середине запущенного сценария. Чтобы возобновить выполнение, введите команду return. • И, наконец, помните, что вы можете остановить запущенный М-файл с помощью сочетания клавиш i Ctrl |-i-;[ О |. Это полезно, если вычисление занимает слишком много времени, если программа MATLAB выдает нежелательные результаты или если при применении команды pause, вы решите, что необходимо полностью остановить выполнение программы.
Практическое занятие А. Алгебра и арифметика (\Z~fy Задачи с 3 по 8 требуют для выполнения модуль Simbolic Math Toolbox (Инструментарий символьной математики). Для выполнения остальных задач этот модуль не требуется. 1. Вычислите следующие величины. (а) 1111-345. (б) е14 и 382801п, каждый результат с точностью до 15 знака. Какое из значений больше? (в) Дроби 2709/1024, 10583/4000 и 2024/765. Какой из результатов наиболее приближен к выражению 1_7? 2. Вычислите до 15 знака следующие величины. (a)cosh(O.l). (б) 1пB). (Подсказка: натуральный логарифм в программе MATLAB называется log, а не In.) (в) arctan(l/2). (Подсказка: инверсная тангенциальная функция в программе MATLAB называется at an, а не arc tan.) 3. Решите (в символьной форме) систему линейных уравнений. Зх + 4у + 5z = 2 2х - Зу + 7z = -1 х - бу + z = 3 Проверьте свой ответ, используя матричное умножение. 4. Попытайтесь решить (в символьной форме) систему линейных уравнений. Зх - 9у + 8z = 2 2х - Зу + 7z = -1 х - бу + z = 3 Что получилось? Вы знаете, почему? Снова проверьте свой ответ, используя матричное умножение. Ответ правильный? 5. Разложите на множители многочлен х4 - у4. 6. Используйте команды simplify или simple, чтобы упростить следующие выражения: а) 1/A + 1/A +1/х)) б) cos2x - sin2x
Практическое занятие А. Алгебра и арифметика 69 7. Вычислите З301, найдя как приближенное значение с плавающей точкой, так и точное целое число (в обычной десятичной форме). 8. Используйте команды solve или zero, чтобы решить следующие уравнения: а) б7х + 32 = 0 (точное решение) б) 67х + 32 = 0 (числовое решение с точностью до 15 знака) в)х3 + рх + q = 0 (решите для х в пределах от р до q) г) е* = 8х - 4 (все возможные решения). Для упрощения можно сначала создать рисунок. 9. Используйте команды plot или ezplot, чтобы построить графики следующих функций. а) у = х3 - хдля-4 < х < 4 б) у = sin A/х2) для-2 < х < 2. Попробуйте решить это с помощью обеих команд. Оба ли результата верны? Если вы применяете команду plot, убедитесь, что используется достаточное количество точек для чертежа. в) у = tan (х/2)для-п < х ^ п и-10 < у < 10. (Подсказка: сначала сделайте чертеж, затем используйте команду axis). г) у — е~х и у = х4 - х2 для-1.5 < х < 1.5 (на одной и той же координатной сетке). 10. Начертите кривые функций х4 и 2х на одном графике и определите, сколько раз они пересекаются. (Подсказка: возможно, вам придется сделать несколько чертежей, используя интервалы разных размеров, чтобы найти все точки пересечения.) А теперь найдите приблизительные значения точек пересечения, используя команду fzero.
ГЛАВА 4. Выход за пределы основ В этой главе мы опишем несколько важных особенностей программы MATLAB и более подробно рассмотрим некоторые концепции, представленные в главе 2. Мы в достаточной мере раскроем внутреннюю структуру программы MATLAB, чтобы усовершенствовать ваши навыки по работе со сложными функциями, выражениями и командами. В конце этой главы мы познакомим вас с несколькими командами MATLAB для математического исчисления. Запрет вывода Некоторые команды программы MATLAB осуществляют избыточный вывод результатов. Например, когда вы присваиваете значение переменной, программа MATLAB отображает это значение. Но, как мы вкратце упоминали в главе 2, вы можете запретить вывод команды, введя после команды точку с запятой, например: >> syms х >> у = х + 7 У = х + 7 >> z = х + 7; >> z Z = х + 7 Точка с запятой не влияет на метод внутреннего выполнения команд программой MATLAB; это видно из того, как программа реагирует на введение команды z. Вы можете также использовать точку с запятой для отделения серии команд, когда вы заинтересованы в выводе результатов только последней команды (далее в этой главе представлено несколько примеров). Как мы отмечали в главе 2, для отделения команд друг от друга можно также применять запятые, но это не приводит к запрету вывода. Если вы используете точку с запятой после графической команды, это не приведет к запрету вывода графика. ^> Наиболее широко точка с запятой используется для запрета распечатки длинного вектора или большой матрицы. Другим объектом, вывод которого вам может понадобиться запретить, является обозначение результата вывода команды. Для этого предназначена команда disp; при введении disp (x) будет выведено на печать значение переменной х, но не будет выведено обозначение и знак равенства (см. ниже):
Глава 4. Выход за пределы основ 71 >> х я 7; disp (x) или » disp(solve('x + tan(y) = 5', 'у')) - atan(x - 5) Классы данных Каждая переменная, которую вы задаете в программе MATLAB, любой ввод и вывод, команда представляют собой массив данных, принадлежащих определенному классу. В этой книге в основном используются следующие типы данных: числа с плавающей точкой, символьные выражения, ряды символов, дескрипторы функций и встроенные функции. В главе 2 мы рассматривали каждый из этих типов. В Табл. 4.1 представлен каждый тип данных, соответствующий этому типу класс (получен посредством команды whos), а также способ создания этого типа. Табл. 4.1. Классы данных программы MATLAB Тип данных Плавающая точка Символьный Строка Дескриптор функции Встроенная функция Класс Double Sym char func t i on_handle inline Способ создания Ввод числа Ввод команды sym или syms Ввод строки, заключенной в простые кавычки Ввод символа @ Ввод команды inline Массив можно представить в виде двухразмерной системы данных. Простое число (или символьное выражение) рассматривается в программе MATLAB как массив 1x1, иногда называемый скаляром. Массив lxn называется строчным вектором, а массив mxl называется столбцовым вектором. (В сущности, строка представляет собой вектор символов.) Массив чисел mxn называется матрицей (см. раздел «Дополнительно о матрицах» ниже). Класс и размер массива каждой заданной вами переменной вы можете увидеть в окне Workspace (Рабочая область), или введя команду whos (см. раздел «Управление переменными» в главе 2). Набор параметров переменной, отображаемый с помощью команды whos, называется рабочей областью.
72 MATLAB Для эффективного использования команд программы MATLAB вы должны уделять повышенное внимание классу данных, использование которых каждая команда допускает в качестве входных и возвращаемых параметров. Входные параметры могут иметь один и более аргументов, отделенных друг от друга запятыми; некоторые аргументы являются необязательными. Некоторые команды, например, команда whos, не требуют какого-либо входных параметров. Текст справки (см. раздел «Онлайновая справка» в главе 1) для каждой команды обычно содержит информацию о том, какие классы входных параметров ожидаются при запуске команды, а также каковы классы возвращаемых параметров. •/ Когда вы вводите пару слов, например, hold on, программа MATLAB интерпретирует второе слово в качестве аргумента, имеющего класс «строка», для команды, заданной первым словом; таким образом, выражение hold on будет эквивалентно выражению hold ( ' on'). Многие команды рассчитаны более чем на один класс входных параметров, хотя иногда в онлайновой справке отмечается только один класс. Такая гибкость может быть удобна в некоторых случаях, но может приводить к ошибкам в других. Например, интегрирующая команда int допускает входные параметры класса «строка», также как и класса «символьный», хотя в тексте справки упоминается только класс «символьный». С другой стороны, предположим, что вы уже задали а=10, Ь=5 и сейчас пытаетесь разложить на множители выражение а2-Ь2, отбросив ваши предыдущие определения, и что вам необходимо объявить переменные символьными: » factor(aA2-bA2) ans = 3 5 5 При этом вы не получите сообщение об ошибке, и причина в том, что команда factor - это команда, которая разлагает целые числа на простые, также как и разлагает выражения на множители. Так как а2-Ь2 = 75 = 3 • 52, то числовая версия команды factor выполняется. Вывод будет совсем не таким, как вы ожидали. При применении других серий команд будьте осторожны, чтобы такие неожиданные выходные параметры не ввели вас в заблуждение. •/ Обратите внимание, что при введении help factor отображается текст справки для числовой версии команды, но внизу дается перекрестная ссылка на символьную версию. Если вы хотите просмотреть текст справки для символьной версии, введите help sym/factor. Такие функции, как factor, имеющие более одной версии, называются перегруженными. Иногда вам будет необходимо преобразовать один класс данных в другой, чтобы заставить выходные параметры одной команды послужить в качестве входных параметров для другой. Например, мы использовали команду double, чтобы преобразовать символьные выражения в числа с плавающей точкой, и команду sym, чтобы преобразовать числа или строки в символьные выражения. Команды
Глава 4. Выход за пределы основ 73 num2str и str2num производят преобразование между числами и строками, а команда char преобразует в строку символьное выражение. Вы можете также использовать команду vectorize для преобразования символьного выражения в векторизованную строку; это потребует добавлять символ точки (.) перед операторами *, / и А в выражениях. Действия со строками Зачастую бывает полезно объединять две или более строки. Самый простой способ сделать это - использовать векторный формат записи программы MATLAB, помня о том, что строка является «строчным вектором» символов. Например, при вводе [stringl, string2] команды stringl и string2 будут объединены в одну строку. Ниже показано полезное применение объединения строк. Вам может понадобиться задать переменную типа «строка», содержащую выражение, которое требует ввода более одной строки. (В большинстве случаев вы можете продолжить ввод на следующей строке, введя три точки (...) и нажав клавишу |Enter|, однако такая операция невозможна в середине строки.) Решение состоит в том, чтобы разбить выражение на более мелкие части и объединить их, как показано ниже: >> eqn = ['left hand side of equation =', ... ' right hand side of equation r] eqn = left hand side of equation = right hand side of equation •/ Обратите внимание, что вывод строки, как и символьный вывод, отображается без отступа. Символьные числа и числа с плавающей точкой Ранее мы упоминали о том, что вы можете осуществлять преобразование символьных чисел в числа с плавающей точкой и обратно с помощью команд double и sym. Вводимые вами числа по умолчанию являются числами с плавающей точкой. Однако, если вы смешаете числа с плавающей точкой и символьные числа в арифметическом выражении, числа с плавающей точкой будут автоматически преобразованы в символьные. Это объясняет, почему вы можете ввести syms x, а затем хА2 без необходимости преобразовывать 2 в символьное число. Ниже приведен другой пример: >> а = 1 а = 1 >> b = a/symB) b =
74 MATLAB 1/2 Программа MATLAB работает таким образом, что некоторые числа с плавающей точкой восстанавливают свои точные значения при преобразовании в символьные числа. Целые числа, рациональные числа с малыми числителями и знаменателями, квадратные корни из малых целых чисел, число тг и некоторые комбинации этих чисел восстанавливаются таким образом. Например: >> с= sqrtC) с = 1.7321 >> sym(c) ans = sqrtC) Так как непросто предсказать, когда программа MATLAB сохранит точные значения, лучшим выходом будет запретить вычисление числового аргумента для sym путем заключения его в одинарные кавычки, т. е. syxn( rl+sqrtC) r). Далее будет показан еще один способ, в котором одинарные кавычки запрещают вычисление. Функции и выражения Мы использовали термины выражения и функции, но не рассматривали подробно отличия между ними. Говоря точнее, если мы задаем f (х) = х3 - 1, тогда f (записанная без каких-либо входных параметров) является функцией, пока f (х) и х3-1 являются выражениями, включающими переменную х. В разговоре мы часто опускаем это различие, называя f (х) или х3-1 функцией, но в программе MATLAB различие между функциями и выражениями является важным. В программе MATLAB выражение может принадлежать либо к классу «строка», либо к классу «символьный». Рассмотрим следующий пример. » f в гхА3 - 1'; » f G) ans = 1 Этот результат может поставить в тупик, если вы ожидаете, что f будет работать как функция. Так как f является строкой, то f G) указывает на седьмой символ в f, который равен 1 (пробелы считаются). Подобно символьному выводу, вывод строки не имеет абзацного отступа от левого края. Это ключ к тому, что ответ выше является строкой (состоящей из одного символа), а не числом с плавающей точкой. Если ввести f E), то сообщения об ошибке не будет, а если ввести f (-10), то оно появится.
Глава 4. Выход за пределы основ 75^ Вы познакомились с тремя способами задания ваших собственных функций, используя символ <? для создания анонимной функции, команду inline (см. главу 2) или М-файл (см. главу 3). Анонимные или «inline» функции по большей части полезны для задания простых функций, которые можно выразить в одной строке, а также для превращения символьного параметра вывода команды в функцию. М-файлы-функции полезны для задания функций, которые требуют несколько промежуточных команд для вычисления результата. Большая часть команд программы MATLAB представляет собой М-файлы, и вы можете извлечь из них некоторые идеи для собственных М-файлов, например, чтобы увидеть М-файл для команды mean, вы можете ввести type mean. Смотрите также раздел «Дополнительно об М-файлах» ниже. Некоторые команды, например, команда ode45 (команда вычисления обыкновенных числовых дифференциальных уравнений (ODE), который мы будем использовать позже, в главе 10) требуют, чтобы их первый аргумент был функцией, а если точнее, либо встроенной функцией (например, ode45(?, [0 2], 1)), либо дескриптором функции, который представляет собой название встроенной функции или М-файл-функцию, предваряемую специальным символом @ (например, ode45(@func, [0 2], 1)). Синтаксис с использованием символа @ был введен в программу MATLAB версии 6; в более ранних версиях программы заменой служило заключение имени функции в одинарные кавычки, чтобы представить ее в виде строки. Но с кавычками или без них введение символьного выражения при первом вводе команды ode45 приведет к отображению сообщения об ошибке. С другой стороны, большинство символьных команд требует в качестве первого аргумента либо строку, либо символьное выражение, но не функцию. Важным отличием строк от символьных выражений является то, что программа MATLAB автоматически заменяет заданные пользователем функции и переменные на символьные выражения, но не на строки. (Это еще одна причина, по которой одинарные кавычки, в которые вы заключаете строку, запрещают вычисление.) Например, если вы введете » h = <?(t) tA3; int(rh(t)', rtr) Warning: Explicit integral could not be found. > In sym.int at 58 In char.int at 9 ans = int(h(t), t) то интеграл невозможно будет вычислить, потому что строка h будет выглядеть, как неизвестная функция. Но если вы введете » syms t, int(h(t), t)
76 MATLAB ans = 1/4Чл4 тогда предыдущее определение h заменится на символьное выражение h(t) перед выполнением интегрирования. Подстановка В главе 2 мы рассмотрели процесс создания анонимной или «inline» функции из выражения. Вы можете включать числа в такую функцию, например, для создания графика или таблицы значений. Но вы можете также напрямую заменять числовые значения на выражения, используя команду subs. Подробности изложены в подразделе «Подстановка в символьных выражениях» в главе 2. Дополнительно об М-файлах Файлы, содержащие выражения программы MATLAB, называются М-файлами. Существует два типа М-файлов: М-файлы-функции, которые принимают аргументы и производят вывод результата, и М-файлы-сценарии, которые выполняют серии выражений программы MATLAB. В главе 3 мы создавали и использовали оба типа. Этот раздел содержит дополнительную информацию по М-файлам. Переменные в М-файлах-сценариях При выполнении М-файла-сценария используются переменные, которые принадлежат вашей рабочей области (отображаются в окне Workspace (Рабочая область)); то есть они содержат значения, заданные вами ранее в сессии программы MATLAB, и сохраняются после того, как выполнение сценария закончится. Рассмотрим показанный ниже однострочный М-файл-сценарий с именем scriptexi.m: и = [12 3 4]; При введении команды scriptexl данный вектор присваивается переменной и, но вывод результата при этом не отображается. А теперь рассмотрим другой М-файл-сценарий с именем scriptex2.m: n = length(и) Если вы заранее не задали и, то после введения команды scriptex2 будет выведено сообщение об ошибке. Однако если вы введете scriptex2 после запуска scriptexl, тогда значение и из первого сценария будет использовано во втором сценарии и результат п = 4 будет отображен на экране. Если вы не хотите, чтобы результирующий вывод зависел от более ранних вычислений в сессии MATLAB, вставьте строку clear all в начало М-файла, как мы предлагали это сделать в главе 3 при рассмотрении структуры М-файлов- сценариев.
Глава 4. Выход за пределы основ Т7_ Переменные в М-файлах-функииях Переменные, которые используются в М-файле-функции, являются локальными, то есть, не оказывают влияния на переменные в вашей рабочей области и не подвергаются никакому влиянию со стороны этих переменных. Рассмотрим показанный ниже однострочный М-файл-функцию с именем sq.m: function z = sq(x) % sq(x) returns the square of x. z = x.A2 Ввод команды sqC) даст ответ 9, независимо от того, заданы или нет х и z в вашей рабочей области. Запуск М-файла не задает эти переменные в рабочей области и не изменяет их параметры, если эти переменные в рабочей области были заданы ранее. Структура М-файлов-функций Первая строка в М-файле-функции называется строкой определения функции; эта строка задает имя функции, а также количество и порядок аргументов ввода и вывода. За строкой определения функции может следовать несколько строк-комментариев, начинающихся со знака процента %. Эти строки называются текстом справки и отображаются при вводе команды help. В показанном выше М-файле sq.m присутствует только одна строка текста справки; она отображается при введении команды help sq. Остальные строки составляют тело функции; они содержат выражения программы MATLAB, которые производят вычисление значений функции. Кроме того, строки комментариев (строки, начинающиеся со знака процента %) могут быть в любой области М-файла. Все выражения в М-файле-функции, которые обычно производят вывод результатов, должны оканчиваться точкой с запятой с целью прерывания дальнейшего вывода. М-файлы-функции могут иметь множество аргументов ввода и вывода. Ниже показан пример файла с именем polarcoordinates.m с двумя аргументами ввода и с двумя аргументами вывода: function [r, theta] = polarcoordinates (x, у) % polarcoordinates (x, у) returns the polar coordinates % of the point with rectangular coordinates (x, y) r = sqrt(xA2 + yA2); theta = atan2 (x, y); Если вы введете polarcoordinates C# 4), то только первый аргумент вывода будет возвращен и сохранен под именем ans; в данном случае ответ равен 5. Чтобы увидеть оба результата вывода, вы должны присвоить эти результаты переменным, заключенным в квадратные скобки:
™ MATLAB >> [г, theta] = polarcoordinates C, 4) г = 5 theta = 0.9273 Введя г = polarcoordinates C, 4), вы можете присвоить первый аргумент вывода переменной г, но вы не сможете получить второй аргумент вывода; в действительности, при вводе theta = polarcoordinates C, 4), переменной theta будет присвоен первый результат вывода: 5. Комплексная арифметика Программа MATLAB выполняет большую часть своих вычислений, используя комплексные числа; то есть числа в форме а + bi, где i = V-1, а а и b являются вещественными числами. Комплексное число i в программе MATLAB представлено как i. Вы, возможно, никогда не столкнетесь с вводом комплексного числа во время сессии, но программа MATLAB часто воспроизводит ответ, включающий комплексные числа. Например, многие полиномы (многочлены) с вещественными коэффициентами имеют комплексные корни: >> solve(rxA2+2*x+2=0r) ans = Оба корня этого квадратного уравнения являются комплексными числами, выраженными в терминах числа i. Некоторые простые функции также возвращают комплексные значения для определенных значений аргумента. >> log(-l) ans = 0 + 3.1416i Вы можете использовать программу MATLAB для вычислений, включающих комплексные числа, с помощью ввода чисел в форме а + b*i. » B + 3*i)*D - i) ans = 11.0000 + lO.OOOOi Комплексная арифметика является мощным и полезным инструментом. Даже если вы не собираетесь использовать комплексные числа, вы должны знать о возможности ответов с комплексными значениями при вычислении выражений MATLAB.
Глава 4. Выход за пределы основ 79 Дополнительно о матрицах В дополнение к обычным алгебраическим методам комбинирования матриц (матричное умножение) мы можем также комбинировать матрицы поэлементно. В частности, если А и В имеют одинаковый размер, тогда выражение А. *В представляет собой поэлементное произведение А и В, то есть матрицу, элемент i, j которой является произведением элементов i и j значений А и В. Аналогично выражение А./В является поэлементным частным А и В, а А.Ас представляет собой матрицу, сформированную возведением каждого элемента А в степень с. Как правило, если f является одной из встроенных математических функций программы MATLAB или является заданной пользователем векторизованной функцией, тогда выражение f (А) представляет собой матрицу, полученную поэлементным вычислением f для А. Посмотрите, что получится, когда вы введете команду sqrt (А), где А - это матрица, заданная в начале раздела «Матрицы» в главе 2. Вспомните, что выражение хC) является третьим элементом вектора х. Аналогично, выражение АB,3) представляет элемент 2,3в матрице А, то есть элемент во второй строке и третьем столбце. Похожим способом вы можете задавать подматрицы. Ввод выражения АB, [2 4] ) воспроизводит второй и четвертый элементы второй строки матрицы А. Чтобы выбрать второй, третий и четвертый элементы этой строки, введите АB,2:4). Подматрица, состоящая из элементов в строках 2 и 3 и столбцах 2, 3 и 4 создается путем введения А B:3,2:4). Запятая сама по себе служит для указания на всю строку или столбец. Например, выражение А(: ,2) указывает на второй столбец матрицы А, а выражение АC, :) - на третью строку. Программа MATLAB располагает несколькими командами для создания специальных матриц. Команды zeros (n, m) и ones(n, m) создают матрицы размером nxm из нулей и единиц соответственно, а команда еуе(п) воспроизводит тождественную матрицу размера пхп. Решение линейных систем Предположим, что А является невырожденной матрицей размером пхп и b есть столбцовый вектор длины п. Тогда ввод выражения х = А\Ь в числовой форме вычисляет уникальное решение для А*х = Ь. Для получения более полных сведений введите help ml divide. Если А и b являются символьными, а не числовыми, тогда выражение х = А\Ь вычисляет решение для А*х = b в символьной форме. Чтобы найти решение в символьной форме, когда оба ввода числовые, введите х = syxn(A) \b. Вычисление значений собственных и векторов собственных Значения собственные квадратной матрицы А вычисляются с помощью eig(A). Команда [U# R] = eig(A) вычисляет как вектора, так и значения собственные.
80 MATLAB Значения собственные являются диагональными элементами диагональной матрицы R, а столбцы матрицы U являются векторами собственными. Ниже представлен пример, демонстрирующий применение команды eig. » А = [3 -2 0; 2 -2 0; 0 11]; » eig(A) ans = 1 -1 2 » [и. и = R] 0 0 1.0000 R = 1 0 0 = 0 -1 0 eig(A) -0. -0. 0. .4082 .8165 .4082 0 0 2 -0 -0 -0 .8165 .4082 .4082 Вектор собственный в первом столбце U соответствует значению собственному в первом столбце R, и наоборот. Они являются числовыми значениями для пар собственных. Для получения вычисленных в символьной форме пар собственных введите [U# R] = eig(sym(A)). Исчисление в программе MATLAB f-^Lr—Q Программа MATLAB имеет в модуле Symbolic Math Toolbox (Инструментарий символьной математики) встроенные команды для осуществления большинства операций базового исчисления. Дифференцирование Вы можете использовать команду diff для дифференцирования символьных выражений, а также для нахождения производной функции, данной в числовой форме (скажем, в виде М-файла). >> syms х, diff (xA3) ans =
Глава 4. Выход за пределы основ 81 Здесь программа MATLAB выводит значение для переменной х. (См. раздел «Переменные по умолчанию» в конце главы.) А вот другой способ: >> f = @(х) хА3; diff ans = Синтаксис для вторых производных выглядит как diff (f(x), 2), а для п-производных - diff (f (х), п). С помощью команды diff можно также вычислять частные производные выражений, содержащих несколько переменных, как в выражении diff (хА2*у# у), но чтобы произвести вычисления нескольких частных по отношению к смешанным переменным, вы должны использовать команду diff многократно, как в выражении diff (diff (sin(x*y/z) , х) # у)). (Не забудьте объявить у и z символьными переменными.) Существует один пример, где дифференцирование должно быть представлено буквой D, а именно, это когда вам необходимо задать дифференциальное уравнение в виде ввода в команду. Например, чтобы использовать команду вычисления обыкновенных числовых дифференциальных уравнений (ODE) в дифференциальном уравнении ху' + 1 = у, необходимо ввести следующее: » dsolve(rx*Dy + 1 = у', гхг) ans = 1 + х*С1 Интегрирование Программа MATLAB может производить вычисление определенных и неопределенных интегралов. Ниже представлен неопределенный интеграл: » int( rxA2r, rx') ans = 1/3*хЛ3 Как и в случае с командой diff, вы можете объявить переменную х символьной, и поместить ее внутри кавычек в строке символов. Обратите внимание, что программа MATLAB не включает в себя константу интегрирования; результат вывода представляет единственную антипроизводную от подынтегрального выражения. Ниже представлен определенный интеграл: >> syxns х, int(asin(x), 0, 1) ans = l/2*pi - 1 Вы, несомненно, знаете, что не каждая функция, отображаемая при исчислении, может быть символически интегрирована, иногда бывает необходимо числовое
82 MATLAB интегрирование. Программа MATLAB имеет две команды для числового интегрирования функции f (x): quad и quadl. Мы рекомендуем применять команду quadl. » hardintegral = int(log(l + хА2)*ехр(-хА2), х, 0, 1) Warning: Explicit integral could not be found. > In sym.int at 58 hardintegral = int(log(xA2 + l)*exp(-xA2) ) , x = 0 .. 1) » quadl(<?(x) log(l + x. A2) e*exp(-x. A2), 0, 1) ans = 0.1539 О Команды quad и quadl не будут принимать Inf или -Inf в качестве границ интегрирования (хотя int будет). Лучший способ оперировать числовым неточным интегралом на бесконечном интервале - это вычислить его на интервалах возрастающей длины, пока результат не стабилизируется. •/ Существует и другая возможность. Если вы введете double (hardintegral), программа MATLAB использует модуль Symbolic Math Toolbox (Инструментарий символьной математики), чтобы вычислить интеграл, даже в бесконечном диапазоне. Программа MATLAB может также работать с несколькими интегралами. Показанная ниже команда вычисляет двойной интеграл n sin х \ j(x2+y2)iydx о о >> syms х у; int(int(xA2 + уА2, у, 0, sin(x)), 0, pi) ans = pi - 32/9 Обратите внимание, что программа MATLAB допускает, что переменная интегрирования в int есть х, если только вы не установили иначе. Заметьте также, что порядок интегрирования такой, как в исчислении, «наизнанку». И наконец, мы можем использовать команду вычисления двойного интеграла dblquad, со свойствами и методами применения которой вы можете познакомиться в онлайновой справке. Пределы Вы можете использовать команду limit для вычисления правых и левых пределов и пределов бесконечности. Например, limsin(xj/x
Глава 4. Выход за пределы основ 83^ >> syms x; limit (sin(х)/х, х, 0) ans = 1 Для вычисления односторонних пределов используйте параметры ' right' и ' left'. Например: » limit(abs(x)/x, x, 0, 'left') ans = -1 Пределы бесконечности можно вычислять, используя символ Inf. » limit((хА4 + хА2 - 3)/C*хА4 - log(x)), x, Inf) ans = 1/3 Суммы и произведения Конечные числовые суммы и произведения можно легко вычислить, используя векторные возможности программы MATLAB и команды sum и prod. Например: » X ш 1:7; >> sum(X) ans = 28 >> prod(X) ans = 5040 Вы можете находить конечные и бесконечные суммы в символьной форме, используя команду symsum. В качестве примера ниже представлена сумма с вложением ряда. у 1 1_ » syms k n; symsumA/к - A/(к + 1)), 1, п) ans = А это хорошо известная бесконечная сумма:
84 MATLAB ЁА- » symsum(l/nA2# 1, Inf) ans = Другой знакомый пример - это сумма бесконечной геометрической серии: >> syms a k; symsum(aAk# 0, Inf) ans = -1/(а-1) Однако обратите внимание, что ответ верен только при условии-1 < а < 1. ^ Команда symsvun использует переменную к как переменную по умолчанию. Для получения более полной информации смотрите раздел «Переменные по умолчанию», расположенный ниже. Серия Тейлора Вы можете использовать команду taylor для создания многочленных выражений Тейлора с заданной степенью в заданной точке. Например, чтобы создать многочлен Тейлора в степени до 9 в точке х = О функции sin x, введите следующее: >> syms х; taylor(sin(х), х, 10) ans = Обратите внимание, что команда taylor (sin(x) , х, 11) даст тот же самый результат, так как нет никаких условий степени 10 в раскрытии по Тейлору выражения sin x. Вы можете также вычислить многочлен Тейлора в точке, отличной от исходной. Например, с помощью этой команды >> taylor(ехр(х), 4, 2) ans = ехрB)+ехрB)*(х-2)+1/2*ехрB)*(х-2)/ч2+1/6*ехрB)*(х-2)/чЗ вычисляется многочлен Тейлора ех, центрированный в точке х = 2. С помощью команды taylor можно также вычислять расширения Тейлора для бесконечности. » taylor(exp(l/xA2), 6, Inf) ans = 1 + 1/х/ч2+1/2/хл4
Глава 4. Выход за пределы основ 85^ Переменные по умолчанию Вы можете использовать любые буквы для обозначения переменных в функциях программы MATLAB или в функциях, задаваемых вами. Например, нет ничего особенного в применении буквы t в представленном ниже выражении, эту букву можно заменить любой другой буквой. >> syms t; diff(sin(tA2)) ans = 2*cos(t*2)*t Однако если в выражении много переменных и вы применяете команду MATLAB, которая не осуществляет точную ссылку на одну из них, тогда вы сами должны сделать ссылку точной, или программа MATLAB использует встроенную иерархию для отличительного разделения переменных. Например, выражение solve ( 'х + У = 3 ') решается для х, а не для у. Чтобы в этом примере решить уравнение для у, вам необходимо ввести solve (rx + у = 3 ' # 'у').В программе MATLAB переменной по умолчанию для команды solve является х. Если х отсутствует в выражении (выражениях), программа MATLAB ищет букву, ближайшую к букве х (где у предшествует w, но w предшествует z, и т. п.). То же самое производится для команд diff, int и многих других символьных команд. Таким образом, выражение syms w z; diff w*z дает результат z в качестве ответа. Иногда программа MATLAB назначает другую первичную переменную по умолчанию. Например, независимая переменная по умолчанию для команды dsolve (одна из команд вычисления обыкновенных числовых дифференциальных уравнений (ODE)) будет обозначена буквой t, а переменной по умолчанию для команды symsum будет к, что было рассмотрено выше. Свойства этих команд подробно раскрыты в онлайновой справке. Воспользуйтесь ею, если у вас возникнут сомнения по поводу переменных по умолчанию для какой-либо команды программы MATLAB. •/ Вычисления в модуле Symbolic Math Toolbox (Инструментарий символьной математики) фактически отсылаются программой MATLAB в другую программу, называемую Maple, для осуществления обработки. Ядро Maple выполняет символьное вычисление и отсылает результат обратно в программу MATLAB. В редких случаях вам может понадобиться прямой доступ к ядру Maple. В версии Professional программы MATLAB это можно сделать с помощью команд maple и xnhelp. Вывод результатов символьного вычисления, также в редких случаях, может включать в себя функции, которые либо не существуют в программе MATLAB, либо которые не преобразуются должным образом в функции программы MATLAB. Это может создать проблемы, когда вы попытаетесь использовать эти результаты в других командах MATLAB. Для помощи в критических ситуациях воспользуйтесь справкой программы MATLAB в окне Help (Справка) и/или используйте команду znhelp для вызова справки по программе Maple.
ГЛАВА 5. Графика программы MATLAB В этой главе мы более подробно рассмотрим графические команды программы MATLAB и самые основные способы обработки и настройки графики. Чтобы просмотреть команды, введите help graphics (для основных графических команд), help graph2d (для двухмерных графических команд), help graph 3d (для трехмерных графических команд) или help specgraph (для специализированных графических команд). Мы уже рассматривали команды plot и ezplot в главе 2. Данную главу мы начнем с рассмотрения более широкого использования этих команд, равно как и некоторых других часто используемых команд для черчения. Затем будут представлены методы настройки и обработки графики. И, наконец, мы познакомим вас с некоторыми командами и техниками для создания и модифицирования изображений и звуков. •/ Для большинства типов графиков, описываемых ниже, используется команда plot, которая чертит график на основе числовых данных, а также команда ezplot, которая отображает графики функций, задаваемых рядом или символьным вводом. Эти команды поначалу могут показаться более простыми для выполнения, но они довольно ограничены в возможностях и мало поддаются настройке. Мы сосредоточимся на тех командах для графического представления данных, которые будут вам наиболее полезны в работе. Двухмерные чертежи Зачастую бывает необходимо начертить кривую на плоскости х-у, где переменная у не задана, как функция х. Существует две основных техники для начертания таких кривых: параметрическое начертание и контурное, или неявное, начертание. Параметрические чертежи Иногда х и у задаются как функции с некоторым параметром. Например, окружность с радиусом 1, центрированная в точке @#0), может быть выражена в параметрической форме как xscosBnt), y=sinBnt), где t может быть значением от 0 до 1. Хотя у не задана, как функция от х, тем не менее вы можете легко начертить эту кривую с помощью команды plot, как показано ниже на Рис. 5.1: >> Т я 0:0.01:1; » plot(cosB*pi*T), sinB*pi*T)) >> axis square
Глава 5. Графика программы MATLAB 87 Если бы мы использовали приращение 0.1 в векторе Т, результатом был бы многоугольник с отчетливо видимыми углами. Когда ваш график имеет углы, которых быть не должно, вам следует повторять процесс с меньшим приращением до тех пор, пока ваш график не станет выглядеть нормально. Здесь также присутствует команда axis square, которая обеспечивает одинаковую шкалу на обеих осях; без этой команды окружность приняла бы вид эллипса. -0.5 0.5 Рис. 5.1. Единичная окружность X2 + у* » 1 Параметрическое начертание можно также производить с помощью команды ezplot. Вы можете получить почти такое же изображение, как на Рис. 5.1, введя следующую команду: » ezplot(rcos(t)', 'sin(t)', [0 2*pi]); axis square Обратите внимание, что мы использовали точку с запятой после команды ezplot, но это не прервет отображение графика. В основном точка с запятой прерывает только текстовый вывод. Контурные и неявные чертежи Контурный чертеж функции с двумя переменными представляет собой кривые уровня функции, то есть множества точек в плоскости х-у, где функция принимает постоянное значение. Например, кривые уровня для х2 + у2 представляют собой окружности, центрированные в начале координат, а уровни представляют собой квадраты из радиусов этих окружностей. Контурные чертежи создаются в программе MATLAB с помощью команд meshgrid и contour. Команда meshgrid создает сетку из точек в прямоугольной области с заданными интервалами. Эта сетка используется командой contour для создания контурного чертежа в заданной области. Вы можете создать контурный чертеж для х2 + у2 следующим образом (см. Рис. 5.2): » [X Y] в meshgrid(-3:0.1:3, -3:0.1:3); » contour(X, Y, X.A2 + Y.A2); axis square
88 MATLAB -3-2-1 0 1 2 3 Рис. 5.2. Контурный чертеж для я? + у* Вы можете определить множество уровней путем включения дополнительного векторного аргумента в команду contour. Например, чтобы начертить окружности с радиусами 1, V2 и V3, введите следующее: >> contour(X, Y, Х.А2 + Y.A2, [12 3]) Векторный аргумент должен содержать, по крайней мере, два элемента; то есть, если вы захотите начертить одноуровневое множество, вам потребуется задать один и тот же уровень дважды. Это полезно для неявного начертания кривой, заданной уравнением в переменных х и у. Например, чтобы начертить окружность радиусом 1 вокруг начала координат, введите следующее: » contour(X# Y, Х.Л2 + Y.A2, [1 1]) А чтобы начертить график лемнискаты х2 - у2 = (х2 + у2) 2, перепишите уравнение в виде (х2 + у2J - х2 + у2 = О и введите следующее (см. Рис. 5.3): » [X У] = meshgrid(-l.l:0.01:l.l, -1.1:0.01:1.1); » contour(X, Y, (X.A2+Y.A2).A2-X.A2+Y.A2/ [0 0]) >> axis square » title(rThe lemniscate xA2-yA2= (xA2+yA2)A2') ¦®* В данном случае мы использовали в заголовке знак Л для отображения возведения в степень. Вы можете также использовать знак _ для отображения символов в нижнем индексе, воспроизвести греческие буквы, поставив перед названием греческой буквы знак обратной косой черты (обратный слэш), например \ theta. Введите doc title и отыщите в разделе «Examples» (Примеры) другие возможности работы, с заголовками; эти возможности позволяют также озаглавливать такие команды, как xlabel и ylabel. Более подробно об оформлении графиков вы можете узнать в разделе «Настройка графики» далее в этой главе.
Глава 5. Графика программы MATLAB 89 Контурные чертежи вы можете также производить с помощью команды ezcontour, а неявное начертание кривой f (х, у) = 0 - с помощью команды ezplot. В частности, вы можете получить почти такое же изображение, как на Рис. 5.2, введя следующую команду: >> ezcontour('хА2+уА2', [-3 3]# [-3 3]); axis square А чтобы получить почти такое же изображение, как на Рис. 5.3, введите следующую команду: » ezplot('(хА2+уА2)А2-хА2+уА2г# ... [-1.1, 1.1], [-1.1, 1.1]); axis square Лемниската х2-у2=(х2+/J 1 08 06 0.4 02 0 -0.2 -04 -0 6 -08 -1 "' -05 0 05 Рис. 5.3. Лемниската Чертежи полей Команда quiver программы MATLAB используется для начертания векторных полей и массивов стрелок. Стрелки могут находиться на равномерно расположенных точках плоскости (если координаты х и у не заданы точно), или их местоположение может быть задано. Иногда требуется совсем немного, чтобы отмасштабировать стрелки, чтобы они не выглядели слишком большими или слишком маленькими. Для этой цели команда quiver использует опциональный аргумент масштаба. Например, представленный ниже код позволяет начертить векторное поле с «седлообразной точкой», где наблюдается притягивание стрелок в сторону оси х и отталкивание от оси у. Вывод результата показан на Рис. 5.4: >> [х, у] = meshgrid(-1.1:0.2:1.1, -1.1:0.2:1.1); >> quiver(x, -у); axis equal; axis off
90 MATLAB I\\\\\\ I \ \ \ \\Ч i \\\\\\ \\ \ \ \\\ \ \ \ \ / \ 1 У \ f t \ Puc. 5.4. Чертеж векторного поля (х, -у) Трехмерные чертежи Программа MATLAB имеет несколько возможностей для создания трехмерных чертежей. Кривые в трехмерном пространстве Для начертания кривых в трехмерном пространстве основной командой является команда plot3. Эта команда работает так же, как и команда plot, за исключением того, что использует три вектора, а не два: один вектор для координаты х, один - для координаты у и один - для координаты z. Например, мы можем начертить спираль, введя следующее: » Т = -2:0.01:2; » plot3(cosB*pi*T), sinB*pi*T), T) -0.5 -1 -1 -0.5 Рис. 5.5. Спираль с координатами хвсов Bnz) , y=sin Bnz)
Глава 5. Графика программы MATLAB 91 Для команды ezplot также существует трехмерный аналог - команда ezplot3; с помощью этой команды можно начертить такую же спираль, как на Рис. 5.5, введя следующее: » ezplot3('cosB*pi*t)', rsinB*pi*t)', 't', [-2, 2]) Поверхности в трехмерном пространстве Существует две основных команды для вычерчивания поверхностей в трехмерном пространстве: mesh и surf. Первая воспроизводит прозрачную сетчатую поверхность, а вторая - непрозрачную затененную. Каждую команду можно использовать двумя различными способами: для вычерчивания поверхностей, в которых координата z задана в качестве функции координат х и у, и для создания параметрических поверхностей, в которых координаты х, у и z задаются в качестве функций двух других параметров. Ниже проиллюстрированы примеры первого способа с командой mesh и второго - с командой surf. Чтобы начертить график z = f (х, у), следует начать с команды meshgrid, как в случае с командой contour. Например, седлообразную поверхность z = х2 - у2 можно начертить, введя следующее: » [X, Y] = meshgrid(-2:(Kl:2, -2:<M:2); » Z = X.*2-Y.*2; mesh(X, Y, Z) -2 -2 Рис. 5.6. Поверхность z = х2 - у* 'езультирующий график выглядит лучше на экране компьютера, так как про- рамма MATLAB закрашивает поверхность, используя цветовую схему, зависящую т координаты z. Вместо этого мы могли бы воспроизвести непрозрачную по- ерхность, заменив команду mesh на команду surf. уществуют также сокращенные команды ezmesh и e«urf; вы можете получить езультат, сходный с тем, что изображен на Рис. 5.6, введя следующее:
92 MATLAB ezmesh('хА2-ул2', [-2# 2 -2# 2]) Если необходимо начертить поверхность, которая не может быть представлена выражением в форме z = f(x# у), например, сферу х2 + у2 + z2 = 1, тогда лучше будет задать параметры поверхности, используя подходящую координатную систему, в данном случае - цилиндрические или сферические координаты. Например, мы можем взять в качестве параметров вертикальную координату z и полярную координату 0 на плоскости х-у. Если г обозначает расстояние до оси z, тогда выражение сферы становится таким г2 + z2 = 1 или таким r = \ll-z2 , отсюда x = yjl-z2 COS в , у = л/1 - z2 sin в . Таким образом, мы можем воспроизвести чертеж, введя следующее: >> [Z, Theta] = meshgrid(-l:0.1:1# @:0.1:2)*pi); » X = sqrt(l-Z.A2).*cos(Theta); >> Y = sqrt(l-Z.A2).*sin(Theta); >> sur?(X, Y, Z); axis square -0.5. -0.5 -1 -1 Рис. 5.7. Единичная сфера х2 + y2 + z2 = 1 Вы можете также начертить поверхность параметрически с помощью команд ezmesh или ezsurf; результат, весьма сходный с результатом на Рис. 5.7, можно получить, введя следующее: >> ezsurf(rsqrt(l-zA2)*cos(t)', .•. 'sqrt(l-zA2)*sin(t)', 'z', [0, 2*pi# -1, 1]); axis equal Обратите внимание, что сначала нам пришлось определить диапазон t, так как эта буква по алфавиту находится перед буквой z; это необходимо было бы сделать, даже если бы z находилась перед t в строках, которые мы ввели. Чтобы не запоминать такое правило, в программе MATLAB 7 вы можете вводить функции
Глава 5. Графика программы MATLAB 93^ с более чем одной переменной в качестве анонимных функций, например, @(Z/ t) sqrt(l-z.A2) .*cos(t); тогда, если вы использовали z в качестве первой переменной ввода, ее диапазон будет задан первым. Окна изображений До сих пор мы рассматривали только те графические команды, которые воспроизводят или модифицируют отдельный чертеж. Но программа MATLAB имеет возможность открывать несколько окон изображений или объединять несколько чертежей в одном окне изображения. Ниже мы рассмотрим несколько основных методов по управлению и работе с окнами изображений. Несколько окон изображений Когда вы выполняете первую графическую команду в сессии программы MATLAB, график отображается в новом окне, озаглавленном Figure 1 (Изображение 1). Последующие графические команды либо модифицируют, либо заменяют график в этом окне. Вы уже видели ранее, что команда hold on предписывает этим новым графическим командам дополнять текущий график, а не заменять. Если вместо этого вам необходимо создать новый график в отдельном окне, оставив прежний график на экране, введите команду figure, чтобы открыть новое окно, озаглавленное Figure 2 (Изображение 2). Это можно сделать и по-другому, выбрав пункт меню New ¦ Figure (Новое ¦ Изображение) из меню File (Файл) в главном окне программы MATLAB или в окне первого изображения. Последующие графические команды будут применены только к этому окну, пока вы не измените ваше текущее окно командой figure (чтобы переключиться с текущего изображения на Figure 1 (Изображение 1), введите команду figured)) или перетащите другое изображение на передний план с помощью мыши. Когда открыто несколько окон изображений, вы можете узнать, какое из них является текущим, введя команду gcf (сокращенно от get current figure (получить текущее изображение)). Наконец, вы можете удалять окна изображений обычным способом с помощью мыши или вводя команду close; более подробно об этом вы можете узнать в онлайновой справке. Панель инструментов изображения Каждое окно изображения имеет панель инструментов, расположенную под строкой меню и содержащую значки (ярлыки) для нескольких элементов меню, в том числе и значки для открытия, сохранения и распечатки изображений. В середине находится несколько значков, соответствующих нескольким элементам меню Tools (Инструменты). Два значка со знаками плюса и минуса служат для управления масштабом (увеличение и уменьшение соответственно). Чтобы увеличить какую-либо точку на вашем графике, щелкните мышью на значке со знаком плюса, а затем щелкните мышью на необходимой вам точке. Вы можете делать это много раз; каждый раз
94 MATLAB масштаб будет изменяться по обеим осям приблизительно в два раза. Однако не следует щелкать слишком быстро, так как двойной щелчок мышью возвращает график к исходному состоянию. Аналогично, щелкая мышью на значке со знаком минуса, можно постепенно уменьшать изображение. Программа MATLAB 7 имеет также значок с изображением руки, который позволяет передвигать мышью график горизонтально и вертикально внутри текущих осей (панорамирование). К дополнительным параметрам масштабирования можно получить доступ, щелкнув правой кнопкой мыши на окне изображения при включенном режиме масштабирования, используя подменю Options (Параметры) в меню Tools (Инструменты) или применяя команду zoom (см. онлайновую справку по этой команде). Щелчок мышью на значке справа с изображением закольцованной стрелки позволяет вращать трехмерные CD) графические объекты. Чтобы больше узнать о ЗЭ-эффектах, выберите команду Camera Toolbar (Панель инструментов камеры) из меню View (Вид) (начиная с MATLAB 6 и выше). Вы можете также изменять ракурс (угол или точку зрения) с помощью команды view. В частности, команда viewB) проецирует изображение на плоскость х-у (вид сверху, со стороны оси z), а команда viewC) отображает его в ракурсе по умолчанию в трехмерном виде, где ракурс (линия зрения) направлен в сторону начала координат из точки с координатами х = -0.5272t, у = - 0.6871t, z = 0.5t, t>0. •/ В программе MATLAB любой двухмерный чертеж может быть представлен в трехмерном виде, и любой трехмерный чертеж может быть спроецирован на плоскость. Таким образом, на Рис. 5.5 (спираль) при использовании команды view B), будет представлена окружность. В программе MATLAB 7 щелчок мышью на значке справа от значка вращения включает инструмент Data Cursor (Указатель данных), который позволяет отображать координаты точки на кривой при щелчке мышью на самой кривой или рядом с нею. Щелчок правой кнопкой мыши в окне изображения дает несколько параметров; изменение Selection Style (Тип выделения) на Mouse Position (Позиция мыши) позволит вам щелкать мышью на произвольной точке на кривой, а не только на точке начальной установки. (Не забывайте, что кривые, начерченные в программе MATLAB, являются кусочно-линейными кривыми, соединяющими конечное число точек установки.) Это может быть особенно полезно после масштабирования, потому что точки установки могут быть отнесены далеко в сторону. Чтобы получить координаты точки другим способом (как в более ранних версиях, так и в MATLAB 7), можно ввести команду ginput A) в окне Command Window (Командное окно); это позволит вам щелкать мышью на любой точке в окне изображения, а не только на кривой. Несмотря на такие возможности, если вы хотите уточнить координаты точки на кривой, лучшим способом будет использовать инструмент Data Cursor (Указатель данных), потому что этот инструмент будет всегда выделять точку на кривой, даже если вы не щелкнете мышью точно на самой кривой.
Глава 5. Графика программы MATLAB 95 Только в программе MATLAB 7 крайний правый значок на панели инструментов открывает три окна вокруг изображения; все они вместе известны под названием Plot Tools (Инструменты черчения), и открыть их вы также можете с помощью команды plot tools. Вы можете также управлять отображением этих трех окон - Figure Palette (Палитра изображения), Plot Browser (Обзор чертежа) и Property Editor (Редактор свойств) - каждым по-отдельности через меню View (Вид). Эти окна предоставляют различные способы редактирования изображений. Многие из этих возможностей доступны из меню Insert (Вставка) и Tools (Инструменты), а также с помощью Plot Edit Toolbar (Панель инструментов редактирования чертежа) из меню View (Вид). Некоторые параметры редактирования мы коротко рассмотрим далее в разделе «Настройка графики», однако возможностей существует гораздо больше, и мы рекомендуем вам поэкспериментировать с этими инструментами. •/ В ранних версиях программы MATLAB, как и в версии MATLAB 7, некоторые более ограниченные возможности редактирования будут доступны, если щелкнуть мышью на значке со стрелкой, находящемся справа от значка печати на панели Figure Toolbar (Панель инструментов изображения), а затем щелкнуть правой кнопкой мыши на самом изображении. Объединение чертежей в одном окне Команда subplot разбивает окно изображения на совокупность более мелких чертежей. Два первых аргумента определяют размеры массива подчертежей, а последний аргумент определяет номер подчертежа (считая слева направо по первой строке, затем также по следующей строке и т.д.), в котором размещается вывод результатов очередной графической команды. В рассмотренном ниже примере, результат которого отображен на Рис. 5.8, воспроизводится массив чертежей 2x2 первых четырех функций Бесселя Jn, 0 ^ п ^ 3. » X = 0:0*05:40; >> for n = 1:4 subplotB, 2, п) plot(X, besselj(n-1, X)) end •/ В программе MATLAB вы можете также создавать подчертежи, используя окно Figure Palette (Палитра изображения), которое можно активировать через меню View (Вид) или использовать как часть комплекса Plot Tools (Инструменты черчения), рассмотренные выше.
96 MATLAB -0.5 Рис. 5.8. Функции Бесселя JO (х) (вверху слева), Л (х) (вверху справа), J2 (х) (внизу слева), J2 (х) (внизу справа) Настройка графики ^ Этот раздел является более «продвинутым». Если хотите, можете пропустить его при первом чтении. До сих пор в этой главе мы рассматривали некоторые широко используемые команды программы MATLAB для создания чертежей и их обработки. Но зачастую для получения более точного результата необходимо настраивать или редактировать графику, которую воспроизводят эти команды. Для этого вы должны иметь представление о некоторых базовых принципах относительно того, как программа MATLAB хранит и отображает графику. Данный раздел в достаточной мере познакомит вас с необходимой информацией. Но если вам понадобятся более полные сведения, вы можете воспользоваться одной из книг, посвященных исключительно графике программы MATLAB, например, «Using MATLAB Graphics» (Использование графики MATLAB), которая поставляется бесплатно (в формате PDF) с программой и может быть доступна в разделе Printable Documentation (Печатная документация) в окне Help (Справка) (в версии MATLAB 5.3 - в разделе Full Documentation Set (Комплект полной документации), доступной по команде helpdesk). Можно также воспользоваться книгой «P. Marchand & О. Holland, Graphics and GUIs with MATLAB , 3rd ed., Chapman 8c Hall/CRC, London, 2002» Когда вы создали изображение, то существует два основных способа его обработки. Текущее изображение можно модифицировать, вводя команды программы MATLAB в окне Command Window (Командное окно), например, такие команды как title и axis square, с которыми мы уже сталкивались. Или вы можете модифицировать изображение с помощью мыши, используя меню и значки на самом окне изображения. Почти все текстовые команды имеют своих двойников,
Глава 5. Графика программы MATLAB 97 копии, которые могут быть выполнены прямо в окне изображения. Поэтому может возникнуть вопрос, а стоит ли тратить силы на знакомство с обеими техниками настройки изображения? Убедительная причина состоит в том, что редактирование в окне изображения зачастую более удобно, особенно при экспериментах с большим количеством изменений, тогда как редактирование изображения с помощью команд MATLAB в М-файле делает все настройки и регулировки воспроизводимыми. Настоящий эксперт по программе MATLAB использует обе техники. В то время как текстовые команды в основном остаются одинаковыми во всех версиях MATLAB, меню и инструменты окон изображений значительно отличаются в версиях 5.3, 6 и 7 программы. Все эти версии имеют инструмент Property Editor (Редактор свойств), но доступ к этому редактору осуществляется по- разному. В программе MATLAB 7 вы можете открыть его с помощью Plot Tools (Инструменты черчения), как описано выше, или через меню View (Вид). В программе MATLAB 6 следует выбрать команду меню Edit ¦ Current Object Properties (Редактирование ¦ Свойства текущего объекта), а в версии 5.3 - команду меню File ¦ Property Editor (Файл ¦ Редактор свойств). Чтобы модифицировать объекты в окне изображения с помощью мыши, в этом окне должен быть активирован режим редактирования. В программе MATLAB 6 и более поздних вы можете включить или отключить режим редактирования, выбрав команду меню Tools ¦ Edit Plot (Инструменты ¦ Редактировать чертеж) или щелкнув мышью на значке со стрелкой справа от значка печати. Когда режим редактирования включен, этот значок со стрелкой выделен, и установлен флажок рядом с пунктом Edit Plot (Редактировать чертеж) в меню Tools (Инструменты). Далее мы рекомендуем вам щелкнуть мышью на объекте в окне изображения для его редактирования. При щелчке мышью на объекте в окне изображения весь объект должен выделяться маленькими черными квадратами. Если этого не произойдет, тогда вам потребуется включить режим редактирования. Аннотирование Чтобы вставлять названия или текст в изображение, вы можете использовать команды text, xlabel, ylabel, zlabel и legend в дополнение к команде title. Команды хlabel, ylabel, zlabel добавляют текст рядом с координатными осями, команда legend отображает «Легенду» изображения, а команда text добавляет текст в заданной точке. Эти команды имеют опциональные аргументы, которые можно использовать для изменения типа или размера шрифта текста. В качестве примера ниже показано, как модифицируется чертеж лемнискаты (см. Рис. 5.3) путем добавления и редактирования текста. » ezplotC (хА2+уА2)А2-хА2+уА2', ... [-1.1, 1.1], [-1.1, 1.1]); axis square; » title('The lemniscate xA2-yA2=( xA2+yA2)A2«, 'FontSize1, ... 2 0, ¦FontName¦, ¦Helvetica¦# ¦FontWeight¦# ¦bold¦); 4-1605
98 MATLAB >> text(О, О, ¦ \leftarrow a node, also an inflection1, ... •FontSize1, 12); >> text@.2, -0.1, 'point for each branch', 'FontSize', 12) >> xlabel x, ylabel у Лемниската x2-y2=(x2+y2J 1 0.8 0.6 0.4 0.2 >• 0 -0.2 -0 4 -0.6 -0.8 -1 ;( -1 ^ ^ 4 ^ -0.5 /4r a node, also an inflection I • / N. point for each branch 1 ^ S 0 0.5 1 X Рис. 5.9. Лемниската с Рис. 5.3 с аннотацией и более крупным заголовком Обратите внимание, что многие символы (например, стрелка, указывающая налево, на Рис. 5.9) можно вставлять в текстовую строку, вводя их названия с предшествующим символом \ (обратный слэш, или косая черта). (Если вы когда- нибудь использовали научную шрифтонаборную программу Т^Х, то правила вам более-менее известны.) В большинстве случаев названия не требуют пояснений. Например, греческую букву п вы получаете, вводя название \pi, знак суммирования Y. ~ вводя либо \Sigma (для заглавной «сигмы»), либо \surn, стрелки, указывающие в различных направлениях, с помощью команд \ left arrow, Xuparrow и т.п. Чтобы узнать больше подробностей и познакомиться с полным списком доступных символов, смотрите пояснения Text Properties (Свойства текста) в окне Help (Справка). Этот листинг вы можете найти с помощью вкладки Search (Поиск) в окне Help (Справка) или введя команду doc text и щелкнув мышью на строке Text Properties (Свойства текста) в нижней части страницы. •/ В программе MATLAB версии 6 и более поздних вы можете вставлять одни и те же типы аннотаций, используя меню Insert (Вставка) в окне Figure (Изображение). В MATLAB 7 гораздо больше типов аннотаций доступно при активировании Plot Edit Toolbar (Панель инструментов редактирования чертежа), Figure Palette (Палитра изображения) и/или Property Editor (Редактор свойств). Вы можете также использовать Property Editor (Редактор свойств), чтобы изменять шрифт текста названия; щелкните мышью на тексте, который хотите изменить, затем перейдите в Property Editor (Редактор свойств).
Глава 5. Графика программы MATLAB 99^ Изменение типа чертежа Другим немаловажным способом изменения типа графики является модифицирование цвета или типа линий чертежа, или изменение пометок и маркировки на осях. С помощью команды plot вы можете изменять цвет графика, чертить штриховой или точечной линией, помечать начерченные точки символами, просто добавляя третий аргумент в строку для каждой пары х-у. Символы для цветов следующие: 'у' -желтый, rmr -пурпурный, 'с' -голубой, rrr -красный, 'д' - зеленый, 'Ь' - синий, 'wr - белый и 'kr - черный. Символы маркеров точек включают в себя 'о' - кружок, 'х' - крест, ' + ' - плюс и '* ' - звездочка. Символы типов линий включают в себя ' - ' - сплошная линия, ': ' - точечная линия и ' -- ' - штриховая линия. Если задан тип точки, но нет типа линии, тогда чертятся только точки, но между ними не чертится соединяющая их линия. (Те же методы работают с командой plot3 на месте команды plot.) Например, вы можете воспроизвести сплошную красную синусоидальную кривую вместе с точечной синей косинусоидальной кривой, помечая все локальные точки максимума на каждой кривой отличительным символом того же цвета, что и чертеж, как показано ниже. >> X = (-2:0.02:2)*pi; Yl = sin(X); Y2 = cos(X); » plot(X, Yl, 'r-f, X, Y2# rb:r); hold on » XI = [-3*pi/2 pi/2]; Y3 = [1 1]; plot(XI, Y3, 'r*') » X2 = [-2*pi 0 2*pi]; Y4 = [1 1 1]; plot(X2, Y4# 'b+') » axis([-7 7 -1.1 1,1]) Здесь вам могут понадобиться пометки на оси х, расположенные как кратные числа п. Это можно сделать с помощью команды set, которая используется для изменения различных свойств графики. Чтобы применить ее к осям, требуется объединить ее с командой gca (get current axes (получить текущие оси)). Представленный ниже код » set(gca# rXTickr, (-2:2)*pi, 'XTickLabel', ... ' -2pi|-pi|0|pi12pi ' , 'FontSize ', 16) в комбинации с ранее представленным кодом получает текущие оси, делает отметки на оси х, идущие от -2п до 2п и кратные п, а затем символически озаглавливает эти отметки (а не в десятичной записи, которая здесь не смотрится). Также увеличивается размер шрифта надписей (до 16 пунктов). Результат показан на Рис. 5.10.
100 MATLAB -2pi -pi 0 pi 2pi Puc. 5.10. Два периода sin x и cos x В этой связи вас может заинтересовать, каким образом присваивать названия отметкам в виде -2п, -п и т.д., вместо -2pi, -pi и т.д. Вы можете сделать это, введя >> set (gca, ' FontName' , ' Symbolr) >> set(gca# 'XTickLabel', r-2p|-p|0|p|2p') шрифтом Symbol, при этом п занимает место, которое отводится букве р в текстовых шрифтах. •/ В программе MATLAB 7 вы можете использовать Property Editor (Редактор свойств), чтобы осуществлять такие типы изменений. Щелкните мышью на кривой и перейдите в Property Editor (Редактор свойств), чтобы изменить ее тип, цвет, толщину и т.д. В трехмерном чертеже можно щелкнуть мышью на поверхности; при этом отобразятся параметры для изменения цвета и других свойств. Чтобы изменить отметки и надписи, щелкните мышью на осях или на пустой области внутри них, чтобы сосредоточить Property Editor (Редактор свойств) на осях. В программе MATLAB 6 щелкните мышью на кривой и выберите команду меню Edit ¦ Current Object Properties (Редактирование ¦ Свойства текущего объекта), чтобы изменить ее свойства, или выберите Edit ¦ Axes Properties (Редактирование ¦ Свойства осей), чтобы изменить шрифт для меток. Полная настройка Как менять другие аспекты изображения? Команды get и set можно использовать для получения полного списка свойств объектов в окне изображения с последующей модифицкацией этих свойств. Эти объекты и свойства организованы в иерархическую структуру, где каждый объект идентифицируется числом с плавающей точкой, которое называется маркером (handle). Если вы введете get(gcf), то получите список свойств текущего изображения (маркер которого возвращается функцией gcf). Некоторые из них могут выглядеть как: Color = [0.8. 0.8. 0.8]
Глава 5. Графика программы MATLAB 101 CurrentAxes = [151.001] Children = [151.001] Здесь Color обеспечивает цвет фона чертежа в координатах красного, зеленого и синего (RGB), где [0 0 0] - черный и [1 1 1] -белый; [0,8. 0.8, 0.8] светло-серый. Обратите внимание, что сочетание CurrentAxes и Children в этом примере имеют одинаковое значение - одноэлементный вектор, содержащий число 151.001 (число может иметь и другую величину, что, в контексте этого абзаца, не принципиально). Это число является маркером текущих осей, значение которого также будет возвращено командой gca (get current axes (получить текущие оси)). Тот факт, что данный маркер также обнаруживается в команде Children, говорит о том, что оси являются дочерними осями изображения, то есть они лежат на один уровень ниже в иерархической структуре. Ввод команды get(gca) выдает список свойств осей, включающий маркеры типа Children, такие объекты, как Line, с помощью которых можно находить данные XData и YData для текущего чертежа. ^ В приведенном выше примере число 151.001 не является точным значением маркера осей, а только его первым местоположением в десятичной форме. Таким образом, при вводе команды get A51.001) будет выведено сообщение об ошибке. Чтобы получить точное значение Children в описанном выше примере, введите get (gcf, 'Children '). Во многих случаях изображение будет иметь несколько дочерних массивов; при этом команда будет возвращать вектор маркеров. Когда вы найдете интересующие вас свойства, их можно изменить с помощью команды set. Например, код >> set (gcf, 'Colors [10 0]) изменяет фоновый цвет границы окна изображения на красный, а код » set(gca, 'Color', [110]) изменяет цвет фона самого изображения (дочернего по отношению к окну изображения) на желтый (который, согласно схеме RGB является наполовину красным, наполовину зеленым). Показанный метод («один за раз») нахождения и модифицирования свойств изображения можно ускорить, используя команду findobj, чтобы обнаружить маркеры всех потомков (дочерних элементов) (главное окно изображения, его потомки, потомки потомков и т.д.) текущего изображения. Можно также ограничить поиск маркерами, содержащими элементы заданного типа. Например, команда findobj ( 'type', 'line') ищет все маркеры объектов, содержащие элемент Line (Линия). Когда вы найдете их, вы можете использовать команду set для изменения атрибута LineStyle (Тип линии) со сплошного на штриховой, и т.д. Кроме того, команды низкоуровневой графики line, rectangle, fill, surface и image можно использовать для создания новых графических элементов внутри окна изображения.
102 MATLAB %/ В программе MATLAB 7 вы можете также просматривать и модифицировать полный список свойств изображения, осей или других объектов, используя Property Editor (Редактор свойств). Щелкните мышью на объекте, а затем щелкните на кнопке Inspector... (Инспектор) в Property Editor (Редактор свойств). Чтобы выбрать само изображение, щелкните мышью на его границе, за пределами осей. В качестве примера для этих техник ниже представлен код, который создает шахматную доску на белом фоне, как показано на Рис. 5.11. >> white = [111]; gray = 0.7*white; » а = [0 1 1 0]; Ь в [ООП]; с =[1 1 1 1]; >> figure; hold on >> for k = 0:1, for j = 0:2:6 fill(a'*c + c'*@:2:6) + k, br*c + j + k, gray) end, end » plot(8*af, 8*br, 'k') >> set(gca, 'XTickLabel', [],'YTickLabel', []) >> set(gcf, 'Color', white); axis square ¦ - ¦ ¦ г ¦ ,V,:: ,-¦,.¦ | > _ ¦ J ¦ _J H H ¦ Рис. 5.11. Шахматная доска Здесь white и gray являются кодом системы RGB для белого и серого цветов. Двойной цикл for рисует 32 темных квадрата на шахматной доске, используя команду fill с показателем j, индексирующим темные квадраты в одном вертикальном столбце, с показателем к = 0, дающим строки с нечетным номером, и с показателем к = 1, дающим строки с четным номером. Обратите внимание, что здесь команда fill имеет три аргумента: матрицу, каждый из столбцов которой дает х-координаты вершин многоугольника (в данном случае - квадрата), вторую матрицу, соответствующие столбцы которой дают у-координаты вершин, и цвет. Мы составили матрицы с четырьмя столбцами, по одной для каждого закрашенного квадрата в отдельном горизонтальном ряду. Команда plot рисует сплошную
Глава 5. Графика программы MATLAB 103 черную линию вокруг доски. Наконец, первая команда set удаляет надписи на осях, а вторая команда set изменяет цвет фона на белый. $г Изображения, анимация и звук В программе MATLAB можно также создавать и обрабатывать полноцветные изображения, анимацию и звуковые файлы. В дополнение к методам работы с командной строкой, рассмотренным ниже, вы можете открыть мультимедийный файл в формате, поддерживаемом программой MATLAB, дважды щелкнув на нем мышью в окне Current Directory (Текущий каталог) или выбрав команду меню File ¦Import Data (Файл ¦Импортировать данные). Изображения Программа MATLAB может считывать, записывать и редактировать различные изображения, сделанные цифровым фотоаппаратом, найденные в Интернете или созданные в самой программе MATLAB. Изображение представляет собой двухмерный массив мелких разноцветных квадратиков, называемых пикселами. Изображение может храниться в файле различных форматов, например, в форматах png, jpeg и gif. В программе MATLAB цветное изображение, имеющее высоту h пикселов и ширину w пикселов, обычно сохраняется одним из двух способов: в виде RGB-изображения или индексированного изображения. RGB-изображение выражается в виде массива hxwx3, так что цвет каждого пиксела задается тремя значениями: глубиной красного, зеленого и синего цвета. (Похожим типом изображения является черно-белое, которое выражается в виде массива hxw глубины цвета пикселов.) Индексированное изображение состоит из массива hxw, совмещенного со вспомогательным массивом схЗ, который называется цветовой картой: каждый элемент в первом массиве представляет индексное значение строки в цветовой карте, и эта строка дает значения RGB для соответствующего пиксела. (Формат, называемый в программе MATLAB форматом RGB, часто называется true color (Реальный цвет) в графическом программировании; индексированное изображение часто называется pseudocolor (Псевдоцвет).) С помощью команды imread можно считать изображение в любом из множества файловых графических форматов; для знакомства с поддерживаемыми форматами обратитесь к онлайновой справке. Некоторые форматы, например, формат png, может сохранять как RGB, так и индексированные изображения. Другие форматы могут сохранять изображение только в одном из этих типов; изображения формата gif всегда индексированные, тогда как изображения формата jpeg никогда не индексируются. Большинство изображений в Интернете сохраняются в формате RGB, кроме файлов формата gif. Чтобы считать RGB-изображение из файла picture.png (используемые в примерах файлы предварительно нужно создать и поместить в рабочий каталог Work программы MATLAB - прим. ред.) и сохранить его в виде массива rgbpic, введите следующее: >> rgbpic = imread('picture.png');
104 MATLAB Вы можете считать индексированное изображение с помощью команды imread, назначив для вывода две переменных: одну для массива изображения и одну для цветовой карты. Затем вы можете преобразовать эти массивы в один RGB-массив с помощью команды ind2rgb. Например: >> [indpic, map] = imread('picture.gif'); >> rgbpic = ind2rgb(indpic, map); •/ Преобразование из RGB в индексированный формат более трудоемко, потому что чаще всего количество цветов в изображении при этом должно быть сокращено; цветовые карты зачастую имеют 256 или менее цветов. Модуль Image Processing Toolbox (Инструментарий обработки изображения) программы MATLAB имеет команду rgb2ind, которая предлагает несколько алгоритмов для осуществления этого преобразования. Команда image показывает изображение в окне изображения. Для отображения RGB-изображения rgbpic просто введите следующее: >> image(rgbpic) >> axis equal tight Вторая команда необязательна, однако она обеспечивает вывод изображения в желаемом формате кадра. Чтобы получить индексированное изображение indpic с цветовой картой тар, введите следующее: > > image(indpic) >> colormap(map) Команда colormap изменяет цветовую карту текущих осей или, при отсутствии аргументов ввода, выводит текущую цветовую карту. Вы можете редактировать изображение, изменяя значения в массиве изображения. Обратите внимание, что при выводе изображения оси помечаются индексами массива изображения. Вы можете использовать функцию масштабирования окна изображения (см. раздел «Окна изображений», рассмотренный ранее в этой главе), чтобы более точно определить индексы конкретной области изображения или даже отдельного пиксела. По крайней мере, теоретически, вы можете в этом случае редактировать изображение как вам угодно, изменяя числа в массиве. Ниже описано, как на практике выполняются некоторые основные манипуляции. О Далее мы рассмотрим, как редактировать RGB-изображения, так как этот формат предоставляет большую свободу действий, чем другие, и вы всегда можете произвести преобразование из индексированного формата в формат RGB, как описано выше. Однако RGB-изображения сохраняются в трехмерных массивах, что может занять некоторое время при использовании. Ранее в этой книге мы рассматривали только двухмерные массивы, и некоторые команды программы MATLAB, работающие с ними, не работают с трехмерными массивами.
Глава 5. Графика программы MATLAB 105 Чтобы отразить изображение сверху вниз или слева направо, вам потребуется просто отразить (реверсировать) массив с помощью команды f lipdixn. Например, код >> image(?lipdim(rgbpic, 2)) отобразит зеркальное отражение изображения слева направо, а если использовать в предыдущей команде ?lipdim(rgbpic, 1), то изображение будет отражено сверху вниз. (Для индексированных изображений и других двухмерных массивов вы можете использовать более эффективные команды fliplr и flipud.) Чтобы обрезать изображение, выберите необходимый подмассив. Например, чтобы удалить 50 пикселов в верхней и нижней частях изображения и 100 пикселов - слева и справа, введите следующее: >> newpic = rgbpicE1:end-50, 101:end-100, :); Тогда вы можете отобразить обрезанное изображение newpic, как описано выше, или сохранить его, как описано ниже. Чтобы проверить цвет отдельного пиксела, вы можете отобразить его RGB-значения в окне Command Window (Командное окно) и/или вывести его в окне изображения. Например, чтобы проверить пиксел из rgbpic в нижнем левом углу, введите следующее: >> rgbpic(end, 1, :) ansA,1,1) = 240 ansA,1,2) = 114 ans(:, :,3 ) = 14 Приведенный выше результат дает (гипотетически) значения красного, зеленого и синего цветов для пиксела. Чтобы увидеть этот цвет в текущем окне изображения, введите image (rgbpic (end, 1, :)). Затем вы можете отрегулировать цвет, как угодно; например, если вы введете rgbpic (end, I, 2) = 180, это увеличит глубину (интенсивность) зеленого цвета, сделав цвет более светлым и с желтым оттенком. Разумеется, изменение отдельного пиксела существенно не изменит изображение в целом, но вы можете также изменить цвет целого блока пикселов или всего изображения с помощью того же способа. Например, чтобы закрасить черным цветом прямоугольник на изображении, установите на ноль все значения в под- массиве, описывающем этот прямоугольник. Таким образом, команда rgbpicD0:60, 90:110, :) = 0 сделает черными все пикселы в квадрате 21x21 пиксел, расположенном в 50 пикселах от верхней границы и в 100 пикселах от левой границы изображения.
106 MATLAB l/ Изменение чисел в массиве, которое мы только что рассмотрели, не изменит изображение, выведенное в окне изображения, до тех пор, пока вы не примените новую команду image. Кроме манипуляций с изображениями, считываемыми в программе MATLAB, вы можете создавать свои собственные изображения для визуализации числовых данных. Например, предположим, что у вас существует массив temp, который содержит температуры для определенного географического региона. Вы можете отобразить температуры в виде индексированного изображения, введя следующее: >> imagesc(temp) Команда images с работает подобно команде image, но, кроме того, перемасштабирует значения в двухмерном массиве таким образом, что наивысшее число соответствует наивысшему пронумерованному цвету, а низшее число соответствует низшему пронумерованному цвету. В действительности, с цветовой картой по умолчанию, теплые регионы будут закрашены красным цветом, а холодные - синим; промежуточные температуры будут закрашены другими оттенками этих цветов. Чтобы отобразить цветовую карту рядом с изображением, введите команду colorbar. Обратите внимание, что числа на этой панели соответствуют числам вашего исходного массива и не зависят от перемасштабирования, произведенного командой imagesc. Если вам нужна другая цветовая карта, вы можете создать свою собственную или использовать одну из цветовых карт, встроенных в программу MATLAB; для выбора введите команду doc colormap. Например, чтобы трансформировать температурную карту, описанную выше, в черно-белое изображение, где белым цветом выделены высокие температуры, черным - низкие, а оттенками серого - промежуточные температуры, введите команду colormap (gray). И в завершение вы можете сохранить изображение в одном из стандартных форматов, например, в формате png, с помощью команды imwrite. Например, чтобы сохранить newpic в файл newpict.png, введите следующее: >> imwrite(newpic, 'newpict.png') ^> В главе 3 было рассмотрено, как сохраняется изображение в формате, подобном png, с использованием команды print или команды File ¦ Save As (Файл ¦ Сохранить как) в меню окна изображения. При этом в файл сохраняется все изображение, включая границу и надписи на осях. Если вы хотите сохранить только изображение внутри осей, используйте команду imwrite. Анимация Самый простой способ создать анимированное изображение - использовать команду comet, которая воспроизводит параметрический чертеж кривой (как это делает команда plot), но, кроме того, вы можете видеть, как кривая вычерчивается с течением времени. Например, приведенный ниже код » Т в @:0.01:2)*pi;
Глава 5. Графика программы MATLAB 107 >> figure, axis equal, axis([-l 1 -11]), hold on >> comet(cos(T), sin(T)) отображает круговое движение. •/ Мы использовали здесь команду hold on, чтобы сохранить не предыдущий график, а свойства осей, которые мы задали. Без команды hold on программа MATLAB вернется к осям по умолчанию, и кривая будет выглядеть не круговой, как требуется, а скорее эллиптической. Для более сложной анимации вы можете использовать команды get frame и movie view. Команда get frame производит захват активного окна изображения в один кадр фильма, а затем команда movieview (доступная в программе MATLAB 6 и более поздних версиях) воспроизводит результат в отдельном окне. Например, приведенные ниже команды воспроизводят фильм с вибрирующей струной. » X - 0:0.01:1; >> for n = 0:50 plot(X, sin(n*pi/5)*sin(pi*X)), axis([0, 1, -2, 2]) M(n+1) = getframe; end >> movieview(M) Команда axis здесь очень важна, поскольку обеспечивает прорисовку каждого кадра фильма в одних и тех же координатных осях. (В противном случае масштаб осей в кадрах будет различным, и результирующий фильм будет вводить в заблуждение.) Точка с запятой после команды get frame также важна, чтобы избежать вывода массы числовых данных с каждым кадром фильма. *=> Убедитесь, что, пока программа MATLAB выполняет цикл, создающий кадры, вы не закрыли активное окно изображения другим окном (например, окном Command Window (Командное окно)). Если вы это сделали, то содержимое другого окна будет сохранено в кадрах фильма. •/ Вы можете также использовать команду movie (которая, в отличие от команды movieview, доступна в MATLAB 5.3) для воспроизведения фильма в текущем окне изображения. Эта команда предоставляет дополнительные параметры, например, регулировку скорости кадров; за подробностями обратитесь к онлайновой справке. После того, как вы создали фильм, вы можете использовать команду movie2avi (в программе MATLAB 6 и более поздних версиях), чтобы сохранить его в файле формата AVI, который является стандартным форматом и может использоваться в других программах для просмотра фильмов, таких как Windows Media Player или QuickTime. Например, чтобы сохранить созданный выше фильм в файл string.avi, введите код movie2avi (И, ' string. avi ').
108 MATLAB Звук Вы можете использовать команду sound для генерации (создания) звука на вашем компьютере (при условии, что компьютер имеет необходимое оборудование). Эта команда берет вектор, оценивает его в форме звукового сигнала и воспроизводит. Синусоидальный вектор соответствует чистому тональному сигналу, а частота синусоидального сигнала определяет основной тон. Таким образом в приведенном ниже примере воспроизводится эпиграф к Пятой симфонии Бетховена. >> х = @:0.1:250)*pi; у = zerosd, 200); z = @:0.1:1000) *pi; >> sound([sin(x), у, sin(x), у, sin(x), у, sin(z*4/5)/ у, ... sin(8/9*x), y# sin(8/9*x), y. sin(8/9*x)# y. sin(z*3/4)]); Обратите внимание, что нулевой вектор у в этом примере создает очень короткую паузу между последовательными звуками. Для команды sound значения вектора ввода должны быть между -1 и 1. Внутри этого диапазона амплитуда вектора определяет громкость звука; чтобы воспроизвести звук с половинной громкостью, вы можете умножить вводный вектор на 0.5. Для вектора с амплитудой более 1 вы можете использовать команду soundsc, чтобы перемасштабировать вектор под диапазон от -1 до 1 перед его воспроизведением. По умолчанию звук воспроизводится со скоростью 8192 фрагмента в секунду, таким образом, длина вектора, разделенная на 8192, будет длиной звука в секундах. Вы можете изменить скорость с помощью необязательного второго аргумента команды sound; при этом изменится как основной тон, так и продолжительность слышимого звука. В программе MATLAB можно считывать и записывать звуковые файлы, но только в двух форматах: wav и аи. Более популярные форматы, например, трЗ, недоступны, но вы можете воспользоваться специализированными программами для преобразования других форматов в формат wav. Команды wavread и wavwrite считывают и записывают звук в этом формате; за подробностями обратитесь к онлайновой справке.
Практическое занятие В. Исчисление, графика и линейная алгебра f/~T^ Задачам 2, 3, 5-7 и частично 10-12 потребуется для выполнения модуль Symbolic Math Toolbox (Инструментарий символьной математики). Остальные задачи выполняются без использования этого модуля. 1. Используйте команду contour для решения следующих задач. (а) Начертите кривые уровня от функции f(X->y) = 3у + у —X в диапазоне, где значения х и у находятся в пределах от -1 до 1 (чтобы получить представление о том, как выглядят кривые вблизи начала координат), и в более широких диапазонах (чтобы получить более развернутую картину). (б) Начертите кривую Ъу Л- у —X = 5 . (в) Начертите кривую уровня от функции f(x, у) = у In X + X In у , которая содержит точку с координатами A # 1). 2. Найдите производные следующих функций, и, если возможно, упростите каждый ответ: (в) /(x) = s (г) /(x) = arcsinBjc + (е) /(*) = ** (ж) /(jc) = arctan(;c2 3. Определите, может ли программа MATLAB вычислить эти интегралы в символьной форме, а для бесконечных интегралов проверьте результаты путем дифференцирования. nil (а) j COSxdx о (б) jxsin(x2)dx
110 MATLAB (в) (г) (д) 4. Вычислите следующие интегралы в числовой форме, используя команду quadl. /г (а) jesinxdx о (б) JVx3+Wjc о 00 (в) \е х dx. В этом случае найдите также ошибку в числовом ответе, путем срав- -00 нения его с точным результатом, найденным в задаче 3. 5. Вычислите следующие пределы: -. sin х (a) lim 1 + C0SX (б) hm *-+-* х + тг (в) limx2e~x 1 (г) lim- *->! JC — J lim sin — (д) lim sin x-+0+ \ 6. Найдите следующие суммы:
Практическое занятие В. Исчисление, графика и линейная алгебра 111 (б) ±гк к=0 оо хк (в) У,—' функция factorial программы MATLAB не работает с символьным вводом, но вы можете использовать либо команду sym(rk!r) или гамма- 00 функцию Г(х) = I e~'tx~ dt, которая в программе MATLAB называется gamma и о которая удовлетворяет условию Т{к +1) = к\ к=-оо I Z — 7. Вычислите многочлен Тейлора с указанной степенью п и точкой с для следующих функций: (б) f(x) = sinx,n = 4 и 6,с = 0 (в) f(x) = sinx,n = 5,с = 2 (г) f(x) = tanx,n = 6,с = О (д) f(x) 8. Начертите следующие поверхности: (а) z = sinjcsin>> для -Ъп<х<Ъп и -Ъл<у<Ъл (б) z = (х2 + y2)cos(x2 + у2)для -1<jc<1h-1<j/<1 9. Создайте 17-кадровый фильм, кадры которого демонстрируют красные круги радиусом 1/2, центрированные в точках Dcos(yVr/8JJ, Dsin(yVr/8 jj, j' = 0,1,..., 16 . Убедитесь, что все круги рисуются в том же самом комплекте осей и что они имеют вид окружности, а не эллипса. 10. В этой задаче мы используем оператор «обратный слэш», или, другими словами, оператор «левое матричное деление», который знаком нам по разделу «Решение линейных систем» в главе 4. (а) Используйте оператор «обратный слэш», чтобы решить систему линейных уравнений в задаче 3 Практического занятия А.
112 MATLAB (б) Теперь попробуйте тот же метод в задаче 4 Практического занятия А. Программа MATLAB находит один ответ, но не все. Вы можете объяснить, почему? Если нет, тогда смотрите ниже задачу 11, а также пункт г текущей задачи. (в) Далее опробуйте метод на следующем примере: - 2со + Зх + Ау - z = 1 -4co-3x + y + 2z = l 2a> + 3x-4y + z = l Проверьте свой ответ путем матричного умножения. г) Наконец, попробуйте применить метод матричного деления на следующем примере: ах + by = и Не забудьте объявить переменные символьными. Ваш ответ должен включать в себя дробь, таким образом, он будет правильным, только когда его знаменатель не равен нулю. Выполните команду det для матрицы коэффициентов этой системы. Сравните со знаменателем. 11. В этой задаче мы имеем дело с матрицами размером 3x3, хотя принципы решения одинаковы для любых размеров. а) Рассмотрим строки квадратной матрицы А. Они являются векторами в трехмерном пространстве и охватывают подпространство размером 3, 2, 1, или, возможно, 0 (если все элементы А равны нулю). Это число называется рангом матрицы А. Команда rank программы MATLAB вычисляет ранг матрицы. Примените эту команду к четырем матрицам коэффициентов в каждой части задачи 10. Прокомментируйте ответ программы MATLAB для четвертой задачи. б) Матрица пхп является невырожденной матрицей, если имеет ранг п. Какая из четырех матриц, вычисленных вами в пункте (а), является невырожденной? в) Другим показателем невырожденности является определитель - фундаментальный результат линейной алгебры; матрица точно является невырожденной, когда ее детерминант не является нулевым. В этом случае существует уникальная матрица В, которая удовлетворяет идентичности АВ = ВА. Мы называем такую матрицу инверсной и обозначаем А. Программа MATLAB может вычислять инверсии с помощью команды inv. Вычислите det (А) для четырех матриц коэффициентов, и для четырех невырожденных матриц, натлдите их инверсии. Примечание: матричное уравнение Ах = b имеет уникальное решение, а именно Х = А Ъ = А\Ъ, когда А является невырожденной матрицей.
Практическое занятие В. Исчисление, графика и линейная алгебра 113 12. Как пояснялось в главе 4, когда вы вычисляете [U# R] = eig(A), каждый столбец U является собственным вектором А, ассоциированным с собственным значением, которое отображается в соответствующем столбце диагональной матрицы R. Это говорит о том, что AU = TJR. а) Проверьте равенство AU = UR для каждой из матриц коэффициентов в задаче 10. б) Фактически ранг А равен рангу U, поэтому, когда А является невырожденной, то U~XAU = R. Таким образом, если две невырожденных матрицы А и В имеют одинаковый набор собственных векторов, тогда факт, что диагональные матрицы меняются местами без изменения результатов, предполагает то же самое и для А и В. Проверьте эти факты для двух матриц: А = 1 0 -1 0 -1 -1 В = 5 2 -8' 3 6 -10 3 3-7 то есть, покажите, что матрицы с собственными векторами являются одинаковыми, и проверьте, что АВ = ВА. 13. Эта задача по обработке данных генетической наследственности взята из главы 12 книги «Applications of Linear Algebra» (Приложения линейной алгебры) С. Rorres и H.Anton, 3rd ed., John Wiley&Sons, New York, 1984. В типичной модели наследственности характеристика потомка определяется генотипом родителей, где присутствуют две независимых возможности получения генов от каждого родителя, скажем, А и а, и каждая из возможностей одинаково вероятна. (А является доминантным геном, а - рецессивным.) Исходя из этого, мы имеем представленную ниже таблицу вероятностей возможных генотипов потомка ддя всех возможных комбинаций генотипов его родителей. Генотип потомка АА Аа Аа Родительский генотип АА-АА 1 0 0 АА-Аа 1/2 1/2 0 АА-аа 0 1 0 Аа-Аа 1/4 1/2 1/4 Аа-аа 0 1/2 1/2 аа-аа 0 0 1
114 MATLAB Теперь предположим, что существует популяция, в которой скрещивание происходит только с чьим-то идентичным генотипом. (Это вполне естественно, если мы рассматриваем управляемую популяцию какого-либо растения.) Далее предположим, что х0, Уо и z0 обозначают процентное соотношение популяции с генотипами АА, Аа и аа соответственно, в начале наблюдения. Затем с помощью э*ш Уп и zn мы обозначаем процентные соотношения в поколении п. Нам важно знать эти числа при п большой величины, а также как они зависят от начальной популяции. Это можно выразить следующим образом: Теперь мы можем использовать таблицу, чтобы выразить отношение между поколениями п и (п+1). Из-за нашего допущения по скрещиванию только первый, четвертый и шестой столбцы являются релевантными. В действительности обнаруживается, что мы имеем приведенное ниже: 1 = zn+-A: (а) Запишите эти уравнения в виде одинарного матричного уравнения Xn+l = MXп, п > 0. Подробно объясните суть элементов столбцовой матрицы Ха, а также коэффициентов квадратной матрицы М. (б) Примените матричное уравнение рекурсивно, чтобы выразить Хп на основе Хо и степени М. (в) Используйте программу MATLAB для вычисления собственных значений и собственных векторов М. (г) Из задачи 12 известно, что MU = UR, где R - диагональная матрица с собственными значениями М. Решите это уравнение для М. Вы видите, что собой представляет выражение /?да = Нтл_>00 Rn ? Используйте это и ваше прежнее значение М на основе R, чтобы вычислить М^ = Ншя^00 М п . (д) Опишите возможное распределение популяции, вычислив M^Xq . (е) Проверьте свой ответ путем прямого вычисления М° для больших специфических значений М. (Подсказка: программа MATLAB может вычислять степени матрицы М, например, с помощью ввода команды МА10.)
Практическое занятие В. Исчисление, графика и линейная алгебра 115 ж) Вы можете изменить в этой задаче фундаментальное допущение, альтернативно предположив, что все представители поколения п должны скрещиваться только с родителем, генотип которого является исключительно доминантным. Вычислите возможное распределение популяции по этой модели. Другие интересные модели представлены в главах 12-14 книги «Applications of Linear Algebra» (Приложения линейной алгебры) С. Rorres и Н. Anton, 3rd ed., John Wiley&Sons, New York, 1984. 14. & Ширина французского флага в 1.5 раза больше высоты, а сам флаг делится на три вертикальные полосы, имеющие (по порядку) синий, белый и красный цвета. Итальянский флаг почти такой же, но синий цвет заменен зеленым. Создайте массив 200x300x3, представляющий французский флаг, просмотрите его в окне изображения, и преобразуйте его в файл формата jpg - tricolore.jpg. То же самое сделайте с итальянским флагом, но на этот раз преобразование произведите в файл italia.jpg. Наконец, создайте фильм, демонстрирующий, как французский флаг превращается в итальянский.
ГЛАВА 6. Программирование Каждый раз при создании М-файла вы пишете компьютерную программу, используя язык программирования MATLAB. Вы можете сделать в программе MATLAB очень многое, даже если будете применить самые основные техники программирования, с которыми мы вас уже познакомили. В частности, мы рассмотрели простые циклы (с использованием команды for) и элементарные способы отладки в главе 3. А в данной главе мы охватим более широкий круг программных команд и техник, пригодных для решения более сложных задач с помощью программы MATLAB. Если вы уже знакомы с каким-либо языком программирования, то вы достаточно легко сможете овладеть большей частью этого материала. •/ Многие команды программы MATLAB сами по себе являются М-файлами, содержимое которых вы можете посмотреть, используя команды type или edit, то есть можно ввести команду type isprixne, чтобы просмотреть М-файл для команды isprime. Вы можете подробно ознакомиться с техниками программирования программы MATLAB, исследуя включенные в состав программы М-файлы. Ветвление Для многих задаваемых пользователем функций вы можете использовать М-файл- функцию, которая выполняет одну и ту же последовательность команд при любом параметре ввода. Однако зачастую возникает необходимость того, чтобы функция выполняла различные последовательности команд в различных случаях, в зависимости от параметра ввода. Это можно сделать с помощью команды ветвления, и, как и во многих других языках программирования, ветвление в программе MATLAB обычно осуществляется с помощью команды if, что будет рассмотрено ниже. Позже мы рассмотрим другую основную команду ветвления, switch. Ветвление с помощью команды if В качестве простого примера ветвления с помощью команды if рассмотрим представленный ниже М-файл-функцию absval.m, который вычисляет абсолютное значение вещественного числа. function у = absval(x) if х >= О У = х; else у = -х; end
Глава 6. Программирование 117 Первая строка этого М-файла говорит о том, что функция имеет параметр ввода х и параметр вывода у. Если значение параметра х не является отрицательным, то выражение после if определяется программой MATLAB как верное. Затем выполняется команда между if и else, чтобы приравнять у к х; при этом программа MATLAB пропускает команду между выражениями else и end. С другой стороны, если значение х отрицательное, программа MATLAB переходит к выражению else и выполняет следующую за этим выражением команду, приравнивая у к -х. Как и в случае с циклом for, использование отступов в представленных выше командах необязательно; оно помогает при чтении кода и производится в программе MATLAB автоматически с помощью встроенного модуля Editor/Debugger (Редактор/Отладчик). \/ Большинство примеров в этой главе будут выводить специфические результаты, если при вводе применять типы данных, отличающиеся от запланированных. Например, М-файл absval.m создан только для скалярных вещественных значений х, но не для комплексных чисел или векторов. Если, например, х является комплексным, тогда выражение х >= 0 проверяет только, не является ли отрицательной вещественная часть х, а вывод значения у будет комплексным в любом случае. Программа MATLAB имеет встроенную функцию abs, которая корректно работает с векторами и комплексными числами. Как правило, за командой if в той же самой строке должно следовать условное выражение, которое программа MATLAB будет проверять на истинность или ложность; смотрите ниже раздел «Логические выражения», в котором рассматриваются доступные выражения и их выполнение. После нескольких промежуточных команд должно следовать (как с командой for) выражение end. В середине может быть одно или более выражений elseif (см. ниже) и/или выражений else (см. выше). Если результат проверки условного выражения положителен, программа MATLAB выполняет все команды между выражением if и первым выражением elseif, else или end, затем пропускает все другие команды до выражения end. Если результат проверки условного выражения ложный, программа MATLAB пропускает все до первого выражения elseif, else или end и продолжает с этого места программы, производя новую проверку в случае присутствия выражения elseif. В представленном ниже примере мы перепишем файл absval.m таким образом, чтобы не требовалось никаких команд, если результат проверки ложный, устраняя необходимость в выражении else. function у = absval(x) У = х; if у < О у = -у; end
118 MATLAB Выражение elseif полезно, если существует более чем две альтернативы, и их можно различить серией тестов на истинность и ложность. В сущности, это эквивалентно выражению else, за которым немедленно следует вложенное выражение if. В представленном ниже примере мы используем выражение elseif в М-файле signum.m, который выполняет следующую функцию (Программа MATLAB имеет встроенную функцию sign, которая обеспечивает выполнение этой функции для основных элементов ввода, которые мы здесь рассматриваем.) function у = signum(x) if х > О у = 1; elseif х == О У - 0; else У я -1; end Здесь, если значение х положительно, тогда значение у задается равным 1, и все команды от выражения elseif до выражения end пропускаются. (В частности, не выполняется проверка в выражении elseif.) Если значение х не положительно, тогда программа MATLAB переходит к выражению elseif и проверяет, равно ли значение х нулю. Если это так, значение у задается равным нулю, в противном случае значение у задается равным -1. Обратите внимание, что программа MATLAB для проверки равенства требует введения двойного знака равенства (==); одинарный знак равенства зарезервирован для присвоения значений переменным. %/ Подобно команде for и другим программным командам, с которыми вы столкнетесь, команда if и ассоциированные с ней команды можно использовать в окне Command Window (Командное окно). Это может быть полезным для приобретения практических навыков по работе с этими командами, но в основном они предназначены для использования в М-файлах. В нашем обсуждении темы ветвления мы главным образом рассматриваем М-файлы- функции; в М-файлах-сценариях ветвление используется не так часто.
Глава 6. Программирование 119 Логические выражения В представленном выше примере мы использовали операторы отношения, такие как >я, > и во, для формирования логического выражения, и давали программе MATLAB инструкции выбора между различными командами, в зависимости от того, истинно или ложно логическое выражение. Чтобы познакомиться со всеми доступными операторами отношения, введите команду help relop. Некоторые из этих операторов, такие как & (AND) (логическое И) и | (OR) (логическое ИЛИ) можно использовать для формирования логических выражений, более сложных, чем для простого сравнения двух чисел. Например, выражение (х > 0) | (у > 0) будет истинным, если х или у (или оба значения) положительны, и ложным, если ни один из них положительным не является. В этом частном примере круглые скобки не являются необходимыми, но обычно составные логические выражения, подобные этим, легче читать, и они меньше подвержены ошибкам, если скобки используются, чтобы избежать неясности. До сих пор в нашем обсуждении темы ветвления мы рассматривали только те выражения, которые можно выполнить как истинные или ложные. Для многих целей этих выражений вполне достаточно, однако вы также можете дополнить if или elseif любым выражением, которое программа MATLAB может выполнить в числовой форме. Фактически программа MATLAB почти не делает различий между логическими выражениями и обычными числовыми выражениями. Давайте посмотрим, что произойдет, если вы введете логическое выражение отдельно в окне Command Window (Командное окно): » 2 > 3 ans = О При вычислении логического выражения программа MATLAB присваивает результату значение 0 (Ложь) или 1 (Истина). Таким образом, если вы введете 2 < 3, ответом будет 1. С операторами отношения программа MATLAB работает так же, как и с арифметическими операторами, так как вывод их результатов является числовым. •/ Программа MATLAB делает различие между выводом операторов отношения и обычных чисел. Например, если вы введете whos после приведенной выше команды, вы увидите, что ans является логическим массивом. Ниже мы приведем пример, как эта возможность может использоваться в краткой форме. Для получения более полной информации введите команду help logical. Вот другой пример: » 2 | 3 ans = 1
120 MATLAB Оператор «логическое ИЛИ», выраженный знаком |, выдает ответ 0, если оба операнда нулевые, и выдает 1, если это не так. Таким образом, в то время как вывод операторов отношения всегда есть 0 или 1, любое не равное нулю значение, вводимое с операторами & (логическое И), | (логическое ИЛИ) и - (логическое отрицание), рассматривается программой MATLAB, как истина, и только 0 рассматривается как ложь. Если с операторами отношения используются векторы или матрицы, а не скаляры, тогда, подобно арифметическим операциям + и .*, логическая операция осуществляется поэлементно, и вывод представляет собой массив нулей и единиц. Ниже представлено несколько примеров: » [2 3] < [3 2] ans = 1 0 >> х = -2:2; х >= 0 ans = 0 0 111 Во втором случае х поэлементно сравнивается со скаляром 0. Для получения более полной информации введите команду help relop. Тот факт, что параметром вывода для операторов отношения является логический массив, вы можете использовать для выбора элементов массива, отвечающих определенным условиям. Например, выражение х(х >=0) дает в качестве результата вектор, состоящий только из неотрицательных элементов х (если точнее, имеющих вещественную часть, не равную нулю). Таким образом, если х = -2:2, как указано выше, то результат будет такой: >> х(х >=0) ans = 0 12 Если логический массив используется для выбора элементов из другого массива, то два массива должны иметь одинаковый размер. Элементы, соответствующие единице в логическом массиве, выбираются, а элементы, соответствующие нулю - нет. В приведенном выше примере результат является таким же, как если бы мы ввели х C:5), но в этом случае 3:5 представляет собой простой числовой массив, задающий числовые индексы элементов для выбора. Далее рассмотрим, как команды if и elseif решают, истинно или ложно выражение. Для выражения, которое вычисляет скалярное вещественное число, условие такое же, как и рассмотренное выше - число, не равное нулю, обрабатывается как истина, а число, равное нулю - как ложь. Причем для комплексных чисел рассматривается только вещественная часть, таким образом, в выражениях if и elseif любое число с вещественной частью, не равной нулю, обрабатывается
Глава 6. Программирование 121 как истина, а число с нулевой вещественной частью обрабатывается как ложь. Более того, если выражение вычисляет вектор или матрицу, выражения if и elseif, тем не менее, должны выводить результат в простом виде - истина или ложь. Соглашение, используемое в программе MATLAB, состоит в том, что все элементы должны быть истинными, а значит, все элементы должны иметь вещественную часть, не равную нулю, чтобы выражение было обработано как истина. F.cnn какой-либо элемент имеет нулевую вещественную часть, тогда выражение обрабатывается как ложь. Вы можете применить способ, которым создается ветвление, при вводе вектора путем инвертирования проверок с помощью оператора - и команд any и all. Например, выражения if х == 0; ...; end выполнят блок команд (представленный здесь в виде ...)» когда все элементы х равны нулю; если бы вам понадобилось выполнить блок команд, когда какой-либо (any) из элементов х равен нулю, вы могли бы использовать форму if х ~= 0; else; ...; end. Здесь сочетание знаков ~= является оператором отношения для понятия «не равно», таким образом, проверка не удается, когда какой-либо элемент х равен нулю, и команды, следующие после выражения else, пропускаются. Того же эффекта вы можете достичь другим способом, используя команду any, которая выдает истину, когда какой-либо элемент массива не равен нулю: if any(x == 0) ; . • .; end (не забывайте, что если какой-либо элемент х равен нулю, то соответствующий условный элемент х == 0 является истиной, то есть, не равен нулю). Подобным образом команда all выдает истину, когда все (all) элементы массива не равны нулю. Ниже представлена серия примеров, иллюстрирующих некоторые особенности логических выражений и ветвления, которые мы только что рассмотрели. Предположим, что вы хотите создать М-файл-функцию, которая вычисляет такую функцию: fsin(jc) I х х Ф 0 тш\ 1 * = о Вы могли бы составить М-файл следующим образом, function у = f(х) if х == 0 у = 1; else у = sin(x)/x; end Это будет хорошо работать, если параметр ввода х является скаляром, и не будет работать, если х является вектором или матрицей. Разумеется, вы могли бы заменить символ /на . / во втором определении значения у и изменить первое
122 MATLAB определение, чтобы значение у имело ту же величину, что и значение х. Но, если значение х имеет как нулевой, так и ненулевой элементы, тогда программа MATLAB объявит выражение if ложным и использует второе определение. Некоторые элементы результирующего массива у будут иметь вид NaN (not a number (не число)), так как выражение 0/0 является неопределенным. Одним из способов заставить работать этот М-файл для векторов и матриц является использование цикла с целью поэлементного вычисления функции с выражением if внутри цикла. function у в f(х) у в ones(size(х)); for n в 1:prod(size(x)) if x(n) ~= 0 y(n) = sin(x(n))/x(n); end end В представленном выше М-файле мы сначала создаем параметр вывода у в виде массива единиц с тем же размером, что и параметр ввода х. Здесь мы используем выражение size(x), чтобы определить количество строк и столбцов х; вспомните, что программа MATLAB обрабатывает скаляр или вектор, как массив с одной строкой и/или одним столбцом. Команда prod(size(x)) выводит число элементов в х. Таким образом, п в выражении for варьируется от 1 до этого числа. Каждый элемент х(п) проверяется на предмет того, является ли он ненулевым, и если это так, то мы производим переопределение соответствующего элемента у(п). (Если выражение х(п) равно 0, то нет нужды переопределять у(п), так как мы еще вначале, во второй строке, задали его равным 1.) •/ Мы сейчас использовали важную функцию программы MATLAB, которая позволяет каждый элемент матрицы соотнести с отдельным индексом; например, если х представляет собой массив 3 х 2, то тогда элементы этого массива могут быть перечислены, как хA), хB), ..., х(б). В этом случае мы избежали использования цикла внутри цикла. Подобным образом мы могли бы использовать команду length(x(:)) вместо prod(size(x)), чтобы подсчитать полное количество элементов в х. Однако следует соблюдать осторожность. Если бы мы не определили заранее, что у имеет одинаковую величину с х, и использовали бы выражение else внутри цикла, чтобы определять у(п) равным 1, когда х(п) равен 0, тогда у оказался бы массивом 1 х б, а не массивом 3 х 2. В этом случае мы могли бы использовать команду у = reshape (у, size(x)) в конце М-файла, чтобы заставить у приобрести тот же размер, что и х. Однако, даже если вид результирующего массива не является важным, будет не лишним заранее определить массив подходящего размера перед его поэлементным вычислением в цикле, так как цикл в этом случае будет выполняться быстрее.
Глава 6. Программирование 123 Рассмотрим модификацию М-файла, представленного выше, function у в ?(х) if х ~= О у в sin(x)./х; return end у = ones(size(x)); for n a l:prod(size(x)) if x(n) ~= 0 y(n) « sin(x(n))/x(n); end end Кроме цикла мы добавили блок из четырех строк, предназначенный для ускорения работы М-файла, если все элементы параметра ввода х являются ненулевыми. Так как программа MATLAB обрабатывает векторы более эффективно, чем циклы, новый М-файл выполняется в несколько раз быстрее, если х имеет большое количество элементов (все ненулевые). Вот как работает этот новый блок из четырех строк. Первое выражение if является истиной, при условии, что все элементы х ненулевые. В этом случае мы определяем выходной параметр у, используя векторные операции программы MATLAB, которые гораздо более эффективны, чем выполнение цикла. Затем мы используем команду return, чтобы остановить выполнение М-файла без запуска любых других команд. (Использование здесь команды return - дело вкуса; вместо этого мы могли бы все оставшиеся команды поместить между выражениями else и end.) С другой стороны, если х имеет один или несколько нулевых элементов, тогда выражение if ложно и М-файл переходит к командам после ближайшего выражения end. Часто бывают ситуации, когда вы можете полностью избежать использования циклов и команд ветвления, применяя логические массивы. Ниже приведен другой М-файл-функция, который выполняет ту же самую задачу, которая продемонстрирована в предыдущих примерах. Его преимущество состоит в большей краткости и эффективности при работе по сравнению с предыдущими М-файлами, так как в этом файле не используются циклы. function у в f(х) у в ones(size(x)); п ¦ (х ~= 0); y(n) = sin(x(n))./x(n);
124 MATLAB Здесь п является логическим массивом того же размера, что и х, со значением 1 в каждой ячейке, где х имеет ненулевой элемент, и с нулями в любых других ячейках. Таким образом, строка, определяющая у(п), только переопределяет элементы у, соответствующие ненулевым значениям х, и оставляет другие элементы равными 1. Ветвление с помощью команды switch Другой основной командой ветвления является команда switch. Эта команда позволяет осуществлять ветвление по нескольким условиям (направлениям) так же просто, как и с двумя, причем условия рассматриваются на равенство. Ниже представлен простой пример с разделением на три условия формирования параметра ввода. function у = count(х) switch х case I у = 'one'; case 2 у = 'two'; otherwise у = 'many'; end Здесь выражение switch вычисляет параметр ввода х, а затем выполнение программы в файле переходит туда, где выражение case имеет то же самое значение, что и параметр ввода. Таким образом, если параметр ввода х имеет значение, равное 1, тогда параметр вывода у определяется в виде строки 'one', если х равен 2, тогда у определяется в виде строки 'two'. После выполнения всех команд, следующих за выбранным условием, программа MATLAB встречает либо другое выражение case, либо выражение otherwise, что приводит к переходу выполнения программы к выражению end. Таким образом, выполняется самое большее - одно условие. Если не найдено соответствий среди выражений case, тогда программа MATLAB переходит к опциональному выражению otherwise или к выражению end. В приведенном выше примере выражение otherwise присутствует, таким образом, параметр вывода определяется, как строка 'many', если параметр ввода не равен 1 или 2. В отличие от команды if команда switch не разрешает векторные выражения, но разрешает строки. Чтобы увидеть пример с использованием строк, введите команду help switch. Эта возможность может быть полезной, если вы захотите создать М-файл-функцию, который использует параметр ввода в виде строки для выбора среди нескольких различных вариантов.
Глава 6. Программирование 125 |/ Хотя строки нельзя сравнивать, используя операторы отношений, такие как == (кроме случаев, когда они имеют одинаковую длину), тем не менее, вы можете сравнить строки в выражениях if или elseif, используя команды strcmp или isequal. Последняя команда чаще используется при сравнении массивов, которые могут иметь различные размеры или даже различные типы данных. Более подробно о циклах В главе 3 вы познакомились с командой for, которая начинает цикл - последовательность команд, выполняющаяся много раз. При использовании команды for вы заранее определяете, сколько раз будет запускаться цикл (хотя это количество может зависеть, например, от информации, вводимой в М-файл-функцию). Иногда может возникнуть необходимость запускать команды в цикле до тех пор, пока не встретится определенное условие, не определяя заранее количество итераций (повторений). Для этого в программе MATLAB существует команда while. ^ Используя команду while, можно легко случайно создать «бесконечный цикл», который будет выполняться бесконечно, так как заданное вами условие никогда не возникнет. Помните, что прервать выполнение такого цикла вы можете с помощью клавиатурного сочетания |[ctri |+||С|: в противном случае вам придется закрыть программу MATLAB. Неограниченные циклы Ниже представлен простой пример М-файла-сценария, который использует команду while для числового суммирования бесконечной серии 1/14 + 1/24 + 1/34 + ..., которое останавливается только тогда, когда элементы становятся настолько малыми (сравнимо с машинной точностью), что числовая сумма перестает изменяться. п = 1; oldsuxn = -1; newsum =0; while newsum > oldsum oldsum = newsum; newsum = newsum + nA(-4); n = n +1; end newsum Здесь мы устанавливаем переменную newsum равной нулю и п равной 1, затем в цикле мы последовательно добавляем пА (-4) к newsum, добавляем 1 к п и повторяем цикл. Назначение переменной oldsum состоит в том, что эта переменная
126 MATLAB отслеживает, насколько изменяется переменная newsum от одной итерации к следующей. Каждый раз, когда программа MATLAB достигает конца цикла, она начинает цикл снова с выражения while. Если переменная newsum больше oldsum, содержимое выражения while является истинным и цикл выполняется снова. Но когда выражение в первый раз становится ложным, что произойдет, когда newsum станет равно oldsum, программа MATLAB переходит к выражению end и выполняет следующую строку, которая отображает конечное значение newsum (результат равен 1.0823 до 5 значащих цифр). Начальное значение -1, которое мы придали переменной oldsum, является произвольным, но оно должно быть отрицательным, чтобы при первом выполнении выражения while его содержимое было истинным; если мы придадим переменной oldsum значение 0, тогда программа MATLAB перейдет к выражению end без какого-либо выполнения команд в цикле. •/ Несмотря на то, что вы можете составить М-файл, как показано выше, без точного определения количества запусков цикла, тем не менее, может быть полезным задать это количество хотя бы приблизительно. Так как вычисления с плавающей точкой на большинстве компьютеров выполняются с точностью до 16 десятичного знака, представленный выше цикл будет запускаться, пока пА (-4) не достигнет величины 10А(-1б); то есть пока п не станет равна 10А4. Таким образом, на большинстве компьютеров вычисление займет очень мало времени. Однако, если степень будет равна 2, а не 4, вычисление будет состоять из 10А 8 операций, что отнимет много времени на большинстве современных компьютеров - достаточно много, чтобы поискать более эффективный способ суммирования серий, например, используя команду symsum, если у вас установлен модуль Symbolic Math Toolbox (Инструментарий символьной математики). DS> Хотя здесь мы классифицировали команду while как циклическую, она также может быть командой ветвления. В действительности типы разрешенных выражений и методов вычисления для выражения while являются точно такими же, как и для выражения If. Смотрите выше раздел «Логические выражения», чтобы- познакомиться ближе с возможными выражениями, которые можно вводить внутрь выражения while. Прерывание цикла Иногда бывает необходимо, чтобы программа MATLAB преждевременно вышла из цикла for, например, при возникновении определенного условия. Или в цикле while может быть вторичное условие, когда необходима проверка в дополнение к основному условию в выражении while. Внутри любого из этих типов цикла вы можете использовать команду break, чтобы заставить программу MATLAB остановить выполнение цикла и перейти к следующей строке после конца цикла. Команда break в основном используется в составе выражения if. В представленном ниже М-файле-сценарии вычисляется та же сумма, что и в предыдущем примере, за исключением того, что в нем вводится точное значение верхнего предела количества итераций.
Глава 6. Программирование 127 newsuxn = 0; for n = 1:100000 oldsuxn = newsum; newsum = newsum + nA (-4) ; if newsum == oldsum break end end newsum В этом примере цикл останавливается после того, как п достигает величины 100000 или когда переменная newsum останавливает изменение, причем неважно, что происходит первым. Обратите внимание, что команда break игнорирует выражение end, ассоциированное с if, и переходит далее к ближайшему выражению end, ассоциированному с командой цикла, в данном случае - с командой for. Другие команды программирования Ниже рассматриваются дополнительные команды и техники программирования. Подфункции Кроме применения в первой строке в М-файле-функции команда function может использоваться и далее в М-файле для задания вторичной функции, или подфункции, которая может быть использована везде в пределах М-файла, но не будет доступна напрямую из командной строки. Например, в представленном ниже М-файле суммируются кубические корни вектора х вещественных чисел: function у = sumcuberoots(x) у = sum(cuberoot(x)); % Subfunction starts here. function z в cuberoot(x) z = sign(x).*abs(x).A(l/3); Здесь подфункция cuberoot извлекает кубический корень х поэлементно. Подфункции можно использовать только в М-файле-функции, но не в М-файле- сценарии. В качестве примеров применения подфункций вы можете посмотреть многие встроенные М-файлы-функции программы MATLAB. Например, при вводе команды type ezplot будет отображено три различных подфункции.
128 MATLAB Массивы ячеек и структур В главе 4 мы рассмотрели несколько типов данных; ранее в этой главе познакомились с еще одним типом, а именно - с логическими массивами. Два других типа данных, полезных в программировании MATLAB - это массивы ячеек и массивы структур. В сущности, массивы ячеек представляют собой «массивы массивов»; элементы массива ячеек могут иметь различные типы данных и различные размеры. Пустой массив ячеек создается с помощью команды cell, но более распространенным способом его создания является способ с использованием фигурных скобок: » са = {1, [2 3], 'four'} са = [1] [1x2 double] 'four' Фигурные скобки используются также для доступа к определенному элементу ячейкового массива; например, введите команду са{2>, чтобы отобразить второй элемент из са. Массивы структур похожи на структуры в языках программирования, подобным языку С; они позволяют присваивать имена элементам массива, а не нумеровать их. Как и в массивах ячеек, элементы могут иметь различные типы и размеры. Одним из способов создания массива структур является команда struct: >> sa = struct('data'# [1 4 9 16 25], 'description', ... 'perfect squares') sa = data: [1 4 9 16 25] description: 'perfect squares' Для доступа к определенному элементу, или «полю», введите имя массива и имя поля, разделив их точкой, например, sa.data. Вы можете использовать такой же синтаксис для создания и добавления полей к структурному массиву. Другой способ определения массива sa производится с помощью представленных ниже команд: >> sa = struct; » sa.data = [1 4 9 16 25]; >> sa.description = 'perfect squares' Первая команда определяет (задает) пустую структуру, а последующие команды добавляют к ней поля. •/ Программа MATLAB имеет также знаковые и беззнаковые целочисленные типы данных; в качестве примера см. онлайновую справку для команд int32 и uint32.
Глава 6. Программирование 129 Команды для синтаксического разбора ввода и вывода Возможно, вы заметили, что многие функции в программе MATLAB позволяют варьировать тип и/или количество аргументов, которые вы задаете в качестве параметра ввода в функции. Вы можете использовать команды nargin, nargout, varargin и varargout в своих собственных М-файлах, чтобы управлять различным количеством аргументов ввода и/или вывода, тогда как для раздельной обработки различных типов аргументов ввода можно использовать команды isnumeric, ischar и т.д. Когда М-файл-функция выполняется, функции nargin и nargout сообщают, соответственно, о количестве аргументов ввода и вывода, которые были заданы в командной строке. Чтобы проиллюстрировать использование команды nargin, рассмотрим представленный ниже М-файл add.m, в котором суммируются два или три аргумента ввода. function s = add(x, у, z) if nargin < 2 error('At least two input arguments are required.') end if nargin ==2 s = x + y; else s = x + у + z; end Сначала М-файл проверяет, не было ли задано менее двух аргументов ввода, и если это так, то выводится сообщение об ошибке и файл закрывается. (Чтобы узнать больше о команде error и связанных с ней командах, смотрите следующий раздел.) Программа MATLAB автоматически проверяет, не использовано ли большее количество аргументов, число которых определено в первой строке М- файла, таким образом, нет необходимости делать это внутри самого М-файла. Если выполнение М-файла доходит до второго выражения if в представленном выше М-файле, мы знаем, что существует либо два, либо три аргумента ввода; выражение if выбирает требуемый способ действия в каждом случае. Например, если вы введете addD,5) в командной строке, тогда в М-файле переменной х будет присвоено значение 4, переменной у - значение 5, а переменная z останется незаданной; таким образом, очень важно использовать команду nargin, чтобы избежать ссылки на переменную z в случаях, когда эта переменная не задана. Чтобы разрешить большее количество возможных значений ввода в файл add.m, можно добавить дополнительные аргументы в первую строку М-файла и добавить больше вариантов (случаев) для команды nargin. Лучший способ сделать это - использовать аргумент ввода varargin. 5-1605
130 MATLAB function s = add(varargin) s = sum([varargin{:} ] ) ; В этом примере все аргументы ввода присваиваются массиву ячеек varargin. Выражение varargin { :} формирует список аргументов ввода, разделенных запятыми. В представленном выше примере мы преобразовываем этот список в вектор, заключая его в квадратные скобки, формируя тем самым корректный ввод для команды sum. Представленные выше примеры М-файлов подразумевают условие, что их аргументы ввода являются числовыми и будут пытаться их добавлять, даже если аргументы таковыми не являются. В некоторых случаях это желательно; например, оба рассмотренных выше М-файла корректно добавят смесь числовых и символьных значений ввода. Однако, если некоторые из аргументов ввода являются строками, то результатом будет либо в высшей степени бессмысленный ответ в числовой форме, либо сообщение об ошибке, которое будет проблематично расшифровать. Программа MATLAB имеет проверочные функции, которые вы можете использовать, чтобы заставить М-файл по-разному обрабатывать различные типы аргументов ввода - либо выполняя вычисления, либо делая вывод вспомогательного сообщения об ошибке, если аргумент ввода имеет непредвиденный тип. Чтобы посмотреть список этих функций, поищите команды, начинающиеся с буквосочетания is, в разделе «Программирование в среде MATLAB» Глоссария. Здесь в качестве примера мы используем команду isnumeric в М-файле add.m, чтобы вывести на экран сообщение об ошибке, если какой-либо из аргументов ввода не является числовым. function s = add(varargin) if -isnumeric([varargin{:}]) error('Inputs must be floating point numbers.') end s = sum([varargin{:} ] ) ; Когда в М-файле-функции определено несколько аргументов вывода, тогда, если количество этих аргументов, заданных при вызове функции, отличается от необходимого, то оставшиеся просто не выводятся. Вспомните, что, если в командной строке не задано аргументов вывода, тогда возвращается один элемент вывода, который присваивается переменной ans. В качестве примера рассмотрим представленный ниже М-файл rectangular.m, который изменяет полярные координаты на прямоугольные. function [x, у] = rectangular(r, theta) х = г.*cos(theta); у = г.*sin(theta);
Глава 6. Программирование 131 Ввод [х, у] = rectangular B, 1) в командную строку сохраняет прямоугольные координаты точки с полярными координатами B, 1) в переменных х и у. Но если вы введете только rectangular B, 1), тогда ответом будет просто х-координата. В представленной ниже модификации файла rectangular.m настраивается вывод результата так, чтобы он представлял комплексное число х + iy, содержащее обе координаты. function [x, у] = rectangular(r, theta) х = r.*cos(theta); у = г.*sin(theta); if nargout < 2 x = x + i*y; end Чтобы ознакомиться с дополнительной информацией и примерами, обратитесь к онлайновой справке для команды varargout и описанных выше функций. Вычисление и дескрипторы функций Команда eval позволяет запускать команду, оформленную в виде строки, так же, как если бы вы ввели эту команду в командной строке программы. Например, ввод команды eval ( ' cos A) r) выдаст тот же результат, что и ввод команды cos(l). Если вся команда, которую вы хотите запустить, содержится в строке str, тогда вы можете выполнить ее, введя eval(str). Обычно команда eval используется в М-файле для определения переменной или запуска команды, имена которых зависят от параметра ввода или переменной цикла; для знакомства с примерами использования введите help eval. Другая полезная функция команды eval заключается в том, что при наличии двух строк ввода она выполняет команду из первой строки, а если та будет ошибочной, выполняет команду из второй строки. Эта форма команды eval дает некоторую гибкость в управлении параметрами ввода анонимной функции. Например, команда >> add = @(х, у, z) eval(rx + у + zr, 'x + y') создает анонимную функцию, которая суммирует либо два, либо три аргумента ввода, подобно рассмотренному выше файлу add.m. •/ Вы можете также создать анонимную функцию с несколькими параметрами вывода, используя команду deal. Например, набрав >> rectangular = @(r, theta) deal(r.*cos(theta), ... r.*sin(theta)) вы создадите функцию, которая преобразует пару полярных координат в пару прямоугольных координат, как в рассмотренном выше файле rectangular.m. Единственная разница в том, что эта функция выдаст сообщение об ошибке, если вы
132 MATLAB зададите только один аргумент вывода. Чтобы использовать либо один, либо два параметра вывода, вы можете использовать двойную форму ввода команды eval, как в примере выше; с подробностями вы разберетесь сами, в качестве упражнения. В главе 4 мы упоминали о дескрипторах функций, которые появились в программе MATLAB 6. Сейчас дескрипторы функций являются предпочтительным способом для назначения функции в качестве параметра ввода в другой функции (например, как команды f zero и quadl), хотя для обратной совместимости многие из этих функций позволяют также вводить имя функции в виде строки. Начиная с MATLAB 7, дескрипторы функций также упрощают запись М-файлов- функций, которые имеют в качестве параметра ввода другую функцию. Например, рассмотренный ниже М-файл iterate, m имеет параметры ввода в виде дескриптора функции (или функции, созданной командой inline), начального значения и числа, задающего количество повторов. function final = iterate(func, init, num) final = init; for k = l:num final = func(final); end Вспомните, что вставка символа @ перед именем встроенной функции или М-файла-функции создает дескриптор для этой функции. Таким образом, введя iterate(@cos, 1,2), получаем числовое значение cos (cos A)), а введя iterate (@cos, 1# 100), получаем приближение к вещественному числу х, для которого cos(x) « х. (Подумайте об этом!) Не забывайте также, что анонимная функция является дескриптором функции. Таким образом, ввод iterate (@(х) 3.9*х*A - х)# 0.5# 100) производит итерацию «логистической карты» f(x) = 3.9хA - х) сто раз, начиная с х = 0.5. ^ Чтобы больше узнать о логистической карте, обратитесь к разделу «Математическая генетика» в главе «Прикладные задачи». %/ В программе MATLAB 6 и более ранних версиях необходимо использовать команду f eval в М-файлах - функциях, подобных файлу iterate.m. В частности, команда final = func (final) в М-файле заменяется на команду final = feval(func, final). При использовании команды feval вводимая функция может быть задана как строка, как дескриптор функции или как функция, задаваемая командой inline. Например, ввод команды feval (ratan2 ', 1, 0) или команды feval (@at an2, 1, 0) эквивалентен вводу команды at ап2 A, 0). Другой полезной в программировании возможностью анонимных функций является то, что их определение может включать в себя параметр, сохраняемый в переменной. (Кроме функций, задаваемых командой inline.) Рассмотрим следующие команды:
Глава 6. Программирование 133 >> с = 3; f = <?(х) с*х; f B) ans = 6 Значение с в момент задания функции f уже было задано и стало встроенным в f, любые последующие изменения с не повлияют на f: >> с = 5; fB) ans = 6 Эту возможность можно использовать в М-файле для определения анонимной функции, которая зависит от параметра ввода. Другое ее назначение - изменять параметр в цикле. Например, данный цикл >> hold on; for с = 1:3 ezplot(@(x) sin(c*x)# [0 2*pi]) end hold off воспроизведет кривые, как на Рис. 3.1. Пользовательский ввод и вывод результата на экран В предыдущем разделе мы использовали команду error, чтобы вывести сообщение на экран, а затем прервать выполнение М-файла. Выводить сообщения на экран можно также и без остановки выполнения М-файла, с помощью команд disp или warning. Вполне понятно, что команда warning предназначена для вывода предупреждающих сообщений, когда М-файл обнаруживает проблему, которая может повлиять на корректность результата, но не обязательно является серьезной. Вы можете запретить предупреждающие сообщения в командной строке или внутри М-файла, используя команду warning off. Существует еще несколько параметров управления предупреждающими сообщениями; для более подробного знакомства введите команду help warning. В главе 4 мы использовали команду disp для отображения вывода команды без отображения строки «ans =». Также вы можете использовать команду disp для отображения на экране информационных сообщений во время выполнения М-файла или для объединения числового вывода и сообщения в одной строке. Например, следующие команды х = 2 + 2; disp([r The answer is ' num2str(x) '•']) присвоят переменной х значение 4, а затем будет выведено сообщение The answer is 4.
134 MATLAB Программа MATLAB также имеет несколько команд, которые запрашивают ввод у пользователя, запускающего М-файл. В конце главы 3 мы рассмотрели три таких команды: pause, keyboard и input. Вкратце, команда pause просто приостанавливает выполнение М-файла до тех пор, пока пользователь не нажмет любую клавишу, тогда как команда keyboard приостанавливает выполнение М-файла и выдает пользователю приглашение, которое может использоваться, как обычный интерфейс командной строки перед тем, как пользователь введет команду return для продолжения выполнения М-файла. Команда input отображает сообщение и позволяет пользователю вводить данные для программы в одной отдельной строке. Например, в программе, которая воспроизводит последовательные приближения к ответу до тех пор, пока не будет достигнута определенная точность (см. раздел «Неограниченные циклы»), вы могли бы добавить представленные ниже строки после выполнения большого количества повторений цикла. answer = input(['Algorithm is converging slowly; ', ... 'continue (yes/no)? '], rsr); if ~isequal(answer, ryesr) return end Здесь второй аргумент ' s r команды input дает программе MATLAB указание не вычислять ответ, введенный пользователем, а просто присвоить его как строку символов переменной answer. Мы используем команду isequal для сравнения ответа со строкой ryesr, так как знак == можно использовать только при сравнении массивов (в данном случае - строк) одинаковой длины. В этом случае мы решили, что М-файл должен прерываться, если пользователь введет что-либо, кроме полного слова yes. Другие способы могли бы представлять собой сравнение только первой буквы answerA) с 'у', остановку только в том случае, если ответ есть ' по', и т. п. Если открыто окно изображения, вы можете использовать команду ginput, чтобы получить координаты точки, которую пользователь выбирает с помощью мыши. В качестве примера приведенный ниже М-файл выводит «X» там, где пользователь щелкает мышью. function xmarksthespot if isexnpty(get @, ' Current Figure')) error('No current figure.') end flag = ~ishold; if flag hold on end
Глава 6. Программирование 135 disp( 'Click on the point where you want to plot an X. ') [x, y] = ginput(l); plot(x, y, 'xk') if flag hold off end Сначала М-файл проверяет, отображено ли текущее окно изображения. Если это так, то переменной flag присваивается значение 1 при условии активной команды hold off, и 0, если активна команда hold on. Причина этого в том, что нам нужна активная команда hold on, чтобы начертить «X», не стирая существующее изображение; но потом нам необходимо восстановить окно изображения в том состоянии, в котором оно было до выполнения М-файла. Затем М-файл отображает сообщение, указывающее пользователю, что делать, выделяет координаты точки с помощью команды ginput(l) и чертит «X» черного цвета в этих координатах. Аргумент 1 команды ginput означает, что это координаты отдельной точки; при использовании этой команды без аргумента будут собираться координаты нескольких точек, и этот процесс прекратится, только когда пользователь нажмет на клавишу iEnterl. ^ В главе 9 вы узнаете, как в программе MATLAB создашь графический интерфейс пользователя (GUI), чтобы улучшить и обогатить взаимодействие пользователя с программой. Отладка В главе 3 мы рассмотрели несколько простых процедур отладки. Одним из предложенных вариантов был вариант вставки команды keyboard в М-файл, например, непосредственно перед строкой, где появляется ошибка, так чтобы вы могли проверить «Рабочую область» М-файла при выполнении в этой точке (например, используя одноименное окно Workspace (Рабочая область)). Более эффективным способом проведения такого типа отладки является использование команды dbstop и связанных с ней команд. С помощью этой команды вы можете разными способами задать в М-файле проверочную точку (точку останова) (breakpoint); например, на определенном номере строки или при появлении ошибки. Для просмотра списка доступных параметров введите команду help dbstop. Когда встречается проверочная точка, в окне Command Window (Командное окно) отображается приглашение командной строки, начинающейся с буквы К, как если бы в М-файл в этой точке была вставлена команда keyboard. Кроме того, положение проверочной точки выделяется стрелкой в окне Editor (Редактор) (который открывается автоматически, если вы уже не редактируете М-файл). В этой точке в окне Command Window (Командное окно) вы можете проверить переменные, используемые в М-файле, задать другую точку останова с помощью
136 MATLAB команды dbstop, очистить (убрать) точки останова командой dbclear и т.д. Если вы готовы продолжать выполнение М-файла, введите команду dbcont для простого продолжения или команду dbstep, чтобы перемещаться по файлу строка за строкой. Вы можете также остановить выполнение М-файла и немедленно вернуться к обычной командной строке с помощью команды dbquit. ¦®* Все рассмотренные в этом разделе функции командной строки вы также можете выполнять с помощью мыши и/или используя комбинации клавиш клавиатуры (быстрые клавиши) в окне Editor (Редактор). Чтобы подробнее познакомиться с командами и возможностями отладки окна Editor (Редактор), обратитесь к разделу «Методики отладки» в главе 11. 1нг Взаимодействие с операционной системой D^> Этот раздел предназначен для более опытных пользователей. При первом чтении вы можете его пропустить и перейти к следующей главе. Вызов внешних программ Программа MATLAB позволяет запускать на вашем компьютере другие программы из своей командной строки. Например, вы можете без проблем вводить команды операционной среды UNIX или DOS для операций с файлами прямо в окне Command Window (Командное окно), не открывая для этого отдельное окно. Или вам может понадобиться использовать программу MATLAB, чтобы изобразить в виде графика результат программы, написанной на языке программирования С или Fortran. Наконец, для проведения крупномасштабных вычислений вы можете комбинировать операции, написанные на другом языке программирования, с операциями, которые вы пишете в программе MATLAB. Самый простой способ запустить внешнюю программу - ввести восклицательный знак в начале строки, а затем команду операционной системы, которую вы хотите запустить. Например, ввод команды !dir в системе Windows или команды !ls -1 в системе UNIX выведет на экран более детализированный список файлов в текущем рабочем каталоге, чем просто команда dir программы MATLAB. В главе 3 мы описывали команду dir и другие команды MATLAB, такие как cd, delete, pwd и type, которые подобны командам из систем UNIX или DOS. Однако для некоторых операций (например, переименование файла) вам может понадобиться запустить необходимую команду из операционной системы. •/ Если вы используете интерфейс операционной системы в М-файле, который хотите запускать в системах Windows или UNIX, вам следует использовать проверочные функции ispc и/или isunix, чтобы использовать те команды, которые применимы для используемой операционной системы, то есть, например, if isunix; ...; else; ...; end. Если вам необходимо отличить различные версии системы UNIX (Linux, Solaris и т.д.), вы можете вместо команды isunix использовать команду computer.
Глава 6. Программирование 137 Результат команды операционной системы, с восклицательным знаком перед ней, может быть только отображен на экране. Чтобы присвоить результат такой команды переменной, вам необходимо использовать команды dos или unix. Хотя каждая из них, согласно документации, работает в своей собственной операционной системе, тем не менее, в современных версиях программы MATLAB они работают как взаимозаменяемые. Например, если вы введете [stat, data] = dos('xnyprog 0.5 1000'), программа с именем myprog будет выполнена с аргументами командной строки 0,5 и 1000, и ее «стандартный вывод» (который обычно появился бы на экране), будет сохранен как строка в переменной data. (Переменная stat будет включать в себя статус закрытия программы, которую вы запускаете; обычно это 0, если программа запускается без ошибки.) Если вывод вашей программы состоит только из чисел, в этом случае команда str2num(data) выдаст в качестве результата вектор, содержащий эти числа. Вы можете также использовать команду sscanf для извлечения чисел из строки data; чтобы узнать подробности, введите команду help sscanf. ?> Программа, которую вы запускаете с помощью команд !, dos или unix, должна находиться в текущем каталоге или в тех каталогах, которые перечислены в переменной path вашей операционной системы, по этим каталогам ваша операционная система производит поиск исполняемых файлов; в пути программы MATLAB поиск не производится. |/ Программа MATLAB рассчитана также на работу со специальными интерфейсами программ, написанных на языках С, Fortran и Java, но эта тема уже выходит за пределы данной книги. Чтобы познакомиться с подробностями, посмотрите раздел External Interfaces (Внешние интерфейсы) в окне Help (Справка). Файловый ввод и вывод В главе 3 мы рассмотрели, как используются команды save и load для передачи переменных между «Рабочей областью» и файлом на диске. По умолчанию переменные записываются и считываются в собственном двоичном формате программы MATLAB, который обозначается файловым расширением .mat. ^ В программе MATLAB 7 используется новый двоичный формат, который не читается более ранними версиями программы. Чтобы произвести сохранение в совместимом формате, введите аргумент -v6 после имени файла в команде save. Вы можете также считывать и записывать текстовые файлы, которые могут быть полезны при обмене данными с другими программами. В команде save введите -ascii после имени файла, чтобы сохранить числа в виде текста с точностью до 8 знаков, или -ascii -double для сохранения с точностью до 16 знаков. При использовании команды load предполагается, что данные находятся в текстовом формате, если имя файла не оканчивается на .mat. Это предоставляет дополнительную возможность для импортирования данных с помощью команд dos или unix в том случае, если ранее вы запускали внешнюю программу и сохранили результаты в файле.
138 MATLAB %/ Начиная с версии 6, программа MATLAB предоставляет также интерактивный инструмент под названием Import Wizard (Мастер импортирования) для чтения данных из файлов в различных форматах; для запуска этого мастера введите uiimport (можно ввести, как опцию, и имя файла), выберите команду меню File ¦ Import Data... (Файл ¦ Импортировать данные) или щелкните правой кнопкой мыши на имени файла в окне Current Directory (Текущий каталог) и выберите команду Import Data... (Импортировать данные). Использование команды uiimport позволяет также импортировать данные, которые вы вырезали или скопировали в системный буфер обмена. Для более полноценного управления файловым вводом и выводом (например, аннотирование числового вывода с помощью текста) вы можете использовать команды foren, fprintf и связанные с ними команды. Чтобы подробно познакомиться с функциями ввода и вывода, введите команду help iof un.
ГЛАВА 7. Публикация и М-книги Программа MATLAB исключительно сильна в линейной алгебре, численных методах и графической интерпретации данных. В этой программе легко программировать, а также ее относительно несложно изучить для дальнейшего применения. Таким образом, программа MATLAB доказала свою ценность для инженеров и ученых, практикующих различные научные техники и методы. Очень часто пользователи и группы пользователей, применяющие программу MATLAB, в первую очередь заинтересованы в числовых и графических результатах, выдаваемых командами, процессами и программами MATLAB. Поэтому для них вполне достаточно работать в окне Command Window (Командное окно) программы MATLAB, в котором они могут легко вывести на экран или экспортировать необходимые результаты вывода. Однако многие пользователи математического программного обеспечения предъявляют дополнительные требования к программе. Во-первых, им необходим математический программный пакет, встроенный в интерактивную среду, в которой можно легко осуществлять изменения и пересчитывать результаты. Во-вторых, им нужен высокоуровневый режим презентации, который объединяет вычисления и графику с текстом, использует различные форматы для ввода и вывода и без проблем взаимодействует с другими программами. Эти дополнительные требования можно удовлетворить, используя ячейки и команду publish или интерфейс М-книги; оба метода были кратко описаны в главе 3. Данная глава углубляется в подробности и рассматривает некоторые важные особенности этих методов. Особенности процесса публикации Как мы уже отмечали в главе 3, простейший способ создать законченную презентацию в программе MATLAB - это подготовить вашу работу в виде М-файла- сценария и использовать команду publish. Чтобы сделать это с надлежащим эффектом, вам сначала следует убедиться, что вы активировали режим ячейки в окне Editor (Редактор) так, чтобы ячейковая структура вашего М-файла была легко читаема. Если вы собираетесь разместить результаты своей работы на web- странице или просто распечатать их для просмотра, лучшим вариантом будет публикация в формате HTML (язык разметки гипертекста, то есть, язык форматирования для web -страниц). Программа MATLAB имеет встроенный web -браузер (к нему можно получить доступ с помощью команды web), который отобразит ваш публикуемый М-файл, как только программа MATLAB закончит процесс его компиляции. Затем вы можете либо распечатать результат прямо из окна браузера, либо скопировать опубликованный М-файл на свой web -сервер. Обратите внимание, что программа MATLAB хранит html-код опубликованного М-файла вместе со всей графикой, которую создает программа (обычно в формате png), в папке с именем html; таким образом, если вы копируете опубликованный файл, убедитесь,
140 MATLAB что копируете и все сопутствующие ему графические объекты. Если вы используете программу MATLAB для создания презентационных слайдов, то будет лучше произвести процесс публикации в файл программы PowerPoint (с файловым расширением .ppt). Чтобы создать хорошо форматированный опубликованный М-файл, вспомните раздел «Публикация М-файл а» в главе 3, в котором рассматривается, как все результаты вывода из отдельной ячейки отображаются вместе, следуя командам MATLAB из этой ячейки. Таким образом, если вы хотите разнообразить комментарии и вычисления, вам необходимо разбить свою работу на несколько ячеек. Комментарии будут отформатированы только в случае их отображения в начале ячейки, таким образом, вам необходимо организовать свою работу в следующем порядке: новая ячейка (то есть, знаки %% в начале строки, причем не важно, что следует за ними - пробел или заголовок ячейки), затем комментарии, затем код программы MATLAB. Ниже в качестве простого примера представлен код, воспроизводящий опубликованное решение задачи 5 (д) из Практического занятия В: %% (в) limit(sinA/х), х, 0# 'right') % This means that every real number in the interval % between -1 and +1 is a "limit point" of sin(l/x) % as x tends to zero. You can see why if you plot % sin(l/x) on the interval [0, 1]. ezplot(sin(l/x)/ [CM]) В некоторых случаях вам может понадобиться форматирование, отличающееся от того, которое отображено в представленном выше примере. Например, вы захотите, чтобы ваш опубликованный М-файл включал в себя уравнение, содержащее математические символы, которые не очень просто отобразить в обычном тексте. В этом случае вы можете набрать символы уравнения в программе Т^Х и вставить это уравнение, используя команду Cell ¦ Insert Text Markup ¦ TeX Equation (Ячейка ¦ Вставить разметку текста ¦ Уравнение ТеХ) из меню в верхней части окна Editor (Редактор). Если вы не знакомы с программой Т^Х, вы можете создавать буквы греческого алфавита, вводя название буквы, предваряемое обратной косой чертой (обратный слэш, \), и можете также создавать подстрочные и надстрочные индексы с помощью символов подчеркивания (_) и вставки символа степени (А). Группирование производится с помощью фигурных скобок ({}). Математические символы имеют названия (обычно пояснительные), начинающиеся с обратной косой черты (\), например, \times - для знака умножения и \surn - для знака сложения. Ниже представлен простой пример файла aboutbessel.m, включающий в себя форматированный текст, подходящий для публикации.
Глава 7. Публикация и М-книги 141 %% Sample M-file About Bessel Functions % The *Bessel Function* J_n(x) can be defined in many ways: % % * For example, for |n| an integer, J_n(x) can be defined % by the formal series expansion % % $$ eA{z(t-l/t)/2} = \sum_{n=-\infty}A\infty tAn J_n(z). $$ % % * Secondly, J_n(x) can be defined as the solution of % % $$ xA2y'f(x) + xy'(x) + (xA2 - nA2)y(x)=0 $$ % % that is non-singular at x = 0 and satisfies a % normalization condition. %% % Here is a graph of some of the Bessel functions: x = 0:0,05:10; for n = 0:5 plot(x, besselj(n, x)), hold on end, hold off В этом примере строки, начинающиеся с символов % и *, создают список, вертикальные черты по сторонам буквы п в третьей строке - это инструкция программе MATLAB назначить данному слову моноширинный шрифт, а не Roman, а звездочки, ограничивающие фразу «Bessel function» являются инструкцией по назначению этим словам полужирного начертания. Если вы публикуете этот пример в программе LAT^X, то код программы Т^Х для уравнений будет включен дословно (идентично). Если вы осуществляете публикацию в формат html, программа MATLAB наберет каждое уравнение в программе Т^Х, сохранит результат в виде графического файла, а затем вставит этот файл в web-страницу. Как уже отмечалось ранее, команда publish работает только с М-файлами- сценариями, но не с М-файлами-функциями. Если вы производите вычисления, требующие наличия М-файла-функции, и хотите опубликовать его, вы можете вызвать М-файл-функцию из публикуемого М-файла-сценария и включить в последний строку type <function M-file>,
142 MATLAB где выражение <function M-file> должно быть заменено именем М-файла. Это обеспечит отображение текста М-файла-функции в публикуемом выводе результатов. Примеры этой операции над опубликованным М-файлом вы можете увидеть в разделе «Численное решение теплового уравнения» в главе 10. Одна из проблем, с которыми вы можете столкнуться, возникает, когда вы публикуете М-файл, имеющий ошибку, или, по крайней мере, содержащий код, который выводит сообщение об ошибке программы MATLAB. (В качестве примера просмотрите решение задачи 6 (в) Практического занятия В в разделе «Ответы к практическим занятиям».) Вы обнаружите, что процесс публикации будет прерываться при возникновении ошибки и остальная часть М-файла выполнена не будет. Эту проблему можно решить путем использования команды publish с параметрами, создавая структуру с требуемыми параметрами. (См. раздел «Массивы ячеек и структур» в главе 6.) Например, наше опубликованное решение М-файла для Практического занятия В было воспроизведено с помощью приведенного ниже кода MATLAB: >> options = struct; >> options.format = 'latex'; >> options.stopOnError = logical(false); >> publish('ExBsols', options) Другим важным моментом является то, что размер графики или текста по умолчанию в опубликованном М-файле может оказаться слишком малым или слишком большим, и не отвечать вашим целям. Вы можете изменить размер изображения по умолчанию с помощью команды меню File ¦ Preferences ¦ Editor/Debugger ¦ Publishing Images (Файл ¦ Параметры ¦ Редактор/Отладчик ¦ Публикация изображений), а изменить таблицу стиля по умолчанию можно с помощью команды меню File ¦ Preferences ¦ Editor/Debugger ¦ Publishing (Файл ¦ Параметры ¦ Редактор/Отладчик ¦ Публикация). Мы решили завершить этот раздел описанием еще одного важного момента, который может возникнуть при публикации в программе LAT^X. В процессе публикации вывод кода LAT^X и графические файлы (на этот раз в формате eps) сохраняются в вашей папке html. Вы можете немедленно запустить командой latex файл с расширением tex или можете вставить его в другой файл программы LAT^X. Если вы делаете второе, то не забудьте удалить строки \documentclass{article} \begin { document} в начале, и строку \ end { document} в конце, а также вам следует переместить строки
Глава 7. Публикация и М-книги 143 \usepackage{graphicx} \usepackage{color} во вводную часть документа, в который вы вставляете код (если только они уже не присутствуют там; в этом случае следует удалить лишние копии). Более подробно об М-книгах Интерфейс М-книги позволяет пользователю программы Windows работать с программой MATLAB, пользуясь специальным документом Microsoft Word вместо окна Command Window (Командное окно). В этом режиме пользователь работает в программе Word на переднем плане и в программе MATLAB, запущенной в фоновом режиме, как автоматический сервер. Строки, которые вы вводите в документ программы Word, передаются в фоновом режиме на сервер MATLAB и там выполняются, после чего вывод возвращается в программу Word, а затем и ввод, и вывод автоматически форматируются. В результате мы имеем активный документ, который можно редактировать, как обыкновенный документ в текстовом процессоре. Например, можно перейти к строкам ввода, которые нуждаются в отладке, внести в них изменения и снова запустить, после чего устаревшие данные вывода будут автоматически заменены на новые. Графический вывод, являющийся результатом работы графических команд программы MATLAB, отображается в документе Word сразу после этих команд. Ошибочный ввод и вывод легко удаляется, расширенное форматирование выполняется так же легко, как и обычная работа с текстовым процессором, и в конце результат вашей сессии MATLAB представляет собой привлекательный, легко читаемый и в высшей степени информативный документ. Конечно, можно и «сжульничать», отредактировав чьи- нибудь результаты; далее мы рассмотрим этот и другие недостатки и достоинства М-книг. ^ Здесь мы исходим из предположения, что М-книги были активированы на вашем компьютере. Если это не так или если вы получаете сообщение об ошибке, связанное с потерей файла m-book.dot, вернитесь к разделу об М-книгах в главе 3, чтобы узнать, как решить эту проблему. Самый распространенный способ запустить интерфейс М-книги - ввести команду notebook в командной строке окна Command Window (Командное окно) или, если вы хотите открыть уже существующую М-книгу, ввести команду >> notebook <M-book> где вместо <M-book> должно стоять название (имя) М-книги, которое обычно имеет расширение .doc. %/ Альтернативным, и в некоторых системах (особенно соединенных в сети) предпочтительным, методом запуска является такой, при котором в первую очередь открывается ранее сохраненная М-книга, причем не важно, как именно: прямо через команду меню File ¦ Open (Файл ¦ Открыть) в программе Word
144 MATLAB или с помощью двойного щелчка мышью на имени файла в программе Windows Explorer (Проводник). Программа Word опознает документ как М-книгу и автоматически запустит сервер программы MATLAB. Будьте осторожны: если у вас установлено более одной версии MATLAB, то программа Word запустит версию, которая была установлена последней. Чтобы избежать этого, вы можете открыть нужную вам версию программы MATLAB перед тем, как откроете М-книгу. Теперь вы можете осуществлять ввод в М-книгу обычным способом. Автоматический сервер программы MATLAB активируется только в том случае, если вы делаете одно из двух: либо используете элементы меню Notebook (Блокнот) программы Word, либо нажимаете сочетание клавиш Is Ctrl l+i Enterl после того, как напечатали команду для программы MATLAB. Вы можете заметить, что ваши команды выполняются немного дольше, чем в обычном окне Command Window (Командное окно) программы MATLAB. Здесь нет ничего необычного, если учесть тот поток информации, которой во время работы постоянно обмениваются программы MATLAB и Word. •/ Если вы хотите начать работать с чистой М-книгой, выберите команду меню (при уже открытой М-книге) File ¦ New M-book (Файл ¦ Новая М-книга) в строке меню программы Word или команду File ¦ New... (Файл ¦ Создать), а затем щелкните мышью на ярлыке m-book.dot. %/ Обратите внимание, что элемент Help (Справка) в строке меню является справкой программы Word, а не MATLAB. Если вы хотите включить справку программы MATLAB, тогда либо введите help или doc (нажав после этого сочетание клавиш Ц Ctrl l+llEnterl^ либо выведите окно Command Window (Командное окно) программы MATLAB на передний план (см. ниже) и используйте справку MATLAB обычным способом. Элементы меню Notebook (Блокнот) А теперь давайте поэкспериментируем с элементами меню Notebook (Блокнот). Первой командой этого меню является команда Define Input Cell (Определить ячейку ввода). Если вы поместите текстовый курсор на любой строке и выберете эту команду, тогда эта строка станет строкой ввода. Чтобы произвести вычисление в этой строке, вам необходимо нажать сочетание клавиш ![ctrl l+lJEnter| или выбрать команду меню Notebook ¦ Evaluate Cell (Блокнот ¦ Вычислить ячейку). Преимуществом этого метода является то, что вы можете создать ячейку ввода, содержащую более чем одну строку. Например, введите следующий код syms х у factor(хА2 - уА2) затем выделите обе строки (щелкните и перетащите указатель мыши) и выберите команду Define Input Cell (Определить ячейку ввода). Нажатие сочетания клавиш |[ Ctrl |+|[Enter| приведет к тому, что обе строки будут вычислены. Вы можете сами
Глава 7. Публикация и М-книги 145 определить, что эти две строки входят в состав одной ячейки ввода, увидев квадратные скобки, которые являются маркерами ячейки. Элемент меню Hide Cell Markers (Скрыть маркеры ячейки) убирает маркеры ячейки с экрана; фактически этот элемент меню является переключателем, который отображает или скрывает маркеры ячейки на экране. Если у вас существует несколько ячеек ввода, вы можете преобразовать их в одну ячейку ввода, выделив их и выбрав команду меню Group Cells (Сгруппировать ячейки). Разбить их по-отдельности вы можете, выбрав команду Ungroup Cells (Разгруппировать ячейки). Если вы щелкнете мышью на ячейке ввода и выберете команду Undefine Cells (Отменить определение ячейки ввода), эта ячейка перестанет быть ячейкой ввода; ее форматирование будет возвращено к формату программы Word по умолчанию. Если вы отмените определение ячейки вывода, она потеряет свой формат, но содержимое ячейки ввода останется без изменений. Если вы выделите некоторую часть вашей М-книги (например, чтобы выделить всю М-книгу, выберите команду меню Edit ¦ Select All (Редактирование ¦ Выбрать все)), а затем выберете команду меню Purge Selected Output Cells (Очистить выбранные ячейки вывода), все ячейки вывода в выделенной области будут удалены. Это особенно полезно, если вы хотите изменить некоторые данные, от которых зависит вывод в выделенной области, а затем вновь вычислить всю выделенную область, выбрав команду Evaluate Cell (Вычислить ячейку). Вы можете в любое время вычислить всю М-книгу, выбрав команду Evaluate M-book (Вычислить М-книгу). Если ваша М-книга содержит цикл, вы можете его вычислить, выделив его и выбрав команду Evaluate Loop (Вычислить цикл), или в данном случае Evaluate Cell (Вычислить ячейку), так как весь цикл находится внутри отдельной ячейки ввода. Зачастую бывает полезно очищать весь вывод в М-книге перед сохранением в целях экономии дискового пространства или времени при повторном открытии, особенно, если в документе содержится графика. Если имеются какие-либо ячейки ввода, которые вы хотите автоматически вычислить при открытии М-книги, выделите их и выберите команду меню Define Autolnit Cell (Автовычисление ячейки). Цвет текста в этих ячейках поменяется с зеленого на темно-синий. Если вам необходимо отделить определенную последовательность (серию) команд, скажем, для повторяющихся вычислений, выделите нужные ячейки и выберите команду меню Define Calc Zone (Определить зону вычисления). Выбранные команды будут вставлены в секцию программы Word (с обозначением границ секции перед секцией и после нее). Если вы щелкнете мышью на секции и выберете команду Notebook ¦ Evaluate Calc Zone (Блокнот ¦ Вычислить зону), то вычисляться будут только команды этой зоны. Последние две кнопки также весьма полезны. Кнопка Bring MATLAB to Front (Вывести MATLAB на передний план) делает следующее: отображает окно Command Window (Командное окно) программы MATLAB, которое было скрыто под М-книгой. Вам может понадобиться ввести несколько команд прямо в окне Command Window (Командное окно), но чтобы их не было в М-книге, например команда help. Наконец, последняя кнопка, Notebook Options (Параметры), выводит
146 MATLAB панель, на которой вы можете производить настройку вашей М-книги: задавать числовой формат, устанавливать размер графических изображений и т.д. Графика М-книги Все команды программы MATLAB для создания графики работают и в М-книгах. Изображение, воспроизведенное графической командой, немедленно отображается под этой командой. Но если вы собираетесь улучшить свою графику в М-книге, вы обнаружите, что при этом весьма желательно модифицировать ячейки ввода, которые ее создают, а не создавать большое количество изображений, повторяя команду с новыми параметрами. Таким образом, при добавлении таких элементов, как xlabel, ylabel, legend, title и т.д., лучше всего будет добавлять их в ячейку ввода графики и производить повторное вычисление. В большинстве случаев весьма желательно, чтобы изображения отображались прямо в М-книге (используется параметр по умолчанию Notebook ¦ Notebook Options ¦ Embed Figures in M-book (Блокнот ¦ Параметры ¦ Вставка изображений в М-книгу)); при этом вам не следует беспокоиться о том, появилось или нет изображение в отдельном окне. Но иногда вам может понадобиться использовать окно изображения совместно с М-книгой, например, чтобы поворачивать чертеж с помощью мыши. Если вы введете команду figure в окне Command Window (Командное окно), чтобы открыть окно изображения, тогда вся последующая графика из М-книги будет отображаться одновременно в окне изображения и в самой М-книге. Наконец, мы дошли до кнопки Toggle Graph Output for Cell (Переключить графический вывод для ячейки), единственной кнопки из меню Notebook (Блокнот), которая ранее не описывалась. Если вы выделите ячейку, содержащую графические команды, и щелкнете мышью на этой кнопке, то после вычисления этой команды не будет выведено никаких графических результатов. Это может быть полезно при использовании совместно с командой hold on, если вы хотите воспроизвести отдельный графический объект, используя несколько командных строк. Дополнительные советы по эффективному использованию М-книг Возможно, вы захотите запустить М-файл-сценарий или М-файл-функцию в М-книге. Для этого вы должны быть уверены, что эти файлы расположены в параметрах пути программы MATLAB, так же, как это было в окне Command Window (Командное окно). Если это условие выполнено, М-файлы выполняются в М-книге точно так же, как в окне Command Window (Командное окно), путем введения их имен и нажатия сочетания клавиш I Ctli l+lEnterl. Выдаваемые ими результаты, как промежуточные, так и окончательные, определяются, как и ранее. В частности, точка с запятой в концах строк является обязательной. Единственное, с чем могут быть проблемы - это команда more. Например, ввод такого кода more on; help print
Глава 7. Публикация и М-книги 147 может сбить с толку программу Word и послужить причиной зависания программы. Чтобы избежать этого, вам понадобится вывести программу MATLAB на передний план и вводить запросы с командой help в окне Command Window (Командное окно). Другой стандартной функцией программы MATLAB, которая не очень хорошо работает в М-книгах, является конструкция из трех точек ... для перевода длинной команды на вторую строку. Программа Word автоматически преобразует три точки в одинарный специальный символ многоточия (...) и таким образом дезориентирует программу MATLAB. Существует два способа решить эту проблему. В любом случае не допускайте использования символа многоточия. (Лучше всего вводить точки через пробел, продолжать ввод, затем вернуться и удалить пробелы. - прим. пер.) Можно отключить функцию автозамены в программе Word, которая преобразует три точки в специальный символ многоточия. Проще всего это делается с помощью нажатия сочетания клавиш I Ctrl l+l[z] после трех точек. Можно также выбрать команду меню Tools ¦ Auto Correct (Сервис ¦ Автозамена) и изменить настройки. Проблема с символом многоточия, описанная в текущем разделе, является лишь одной из многих проблем такого рода. Различные виды автоматического форматирования, которые предоставляет программа Word, конфликтуют с программой MATLAB. Вот несколько ярких примеров: дроби (сочетание 1/2 преобразуется в одинарный символ S); сочетание символов :) (конструкция, часто используемая для определения строк матрицы) программа Word преобразует в улыбающееся лицо (смайлик) ©; разнообразие черточек вносит хаос в попытки программы MATLAB интерпретировать обыкновенный дефис, как знак вычитания. Поэкспериментируйте с командой меню Tools ¦ Auto Correct (Сервис ¦ Автозамена) программы Word и, если вы регулярно используете М-книги, отключите некоторые из параметров. А вот еще более серьезная проблема. Если вы вырезаете и вставляете строки символов в ячейку ввода, символы с оригинальным (исходным) шрифтом могут быть преобразованы в нечто не совсем понятное в ячейке ввода со шрифтом Courier. Невероятные и маловразумительные сообщения об ошибках при выполнении являются предупреждением об этой проблеме. В общем, вам не следует копировать ячейки для вычисления, если только это не ячейка, которая уже была успешно вычислена; гораздо безопаснее будет ввести новую строку. Наконец, нам встречались примеры, в которых без какой-либо видимой причины прерывалось вычисление ячейки. Если это происходит и у вас, попробуйте снова нажать сочетание клавиш II Ctrl l+IFnterl. Если это не даст результатов, то вашим единственным выбором будет удалить сбойную ячейку и ввести ее заново.
ГЛАВА 8. Программа Simulink Щ В этой главе мы рассмотрим модуль Simulink, программу из пакета MATLAB, предназначенную для моделирования динамических процессов и инженерных систем. Информации этой главы, вместе с онлайновой документацией, будет вполне достаточно, чтобы научить вас основам работы с программой Simulink. Простое дифференциальное уравнение Если вы хотите хорошо изучить программу Simulink, вы можете воспользоваться серьезным, исчерпывающим документом в формате PDF, доступным по адресу: v\A^w.mathworks.com/access/helpdesk/help/pdf_doc/simulink/sl_using.pdf Мы же приводим в этой главе краткое введение для пользователя, который желает быстро начать работать с программой Simulink. Запустить программу можно, дважды щелкнув мышью на ярлыке Simulink панели запуска, либо щелкнув мышью tuft. на кнопке Simulink Щ, расположенной на панели инструментов Рабочего стола программы MATLAB, или просто введя команду simulink в окне Command Window (Командное окно). При этом открывается окно Simulink library (Библиотека Simulink); такое окно для UNIX-подобных систем отображено на Рис. 8.1. В системах семейства Windows открывается окно Simulink Library Browser (Обзор библиотеки Simulink), показанное на Рис. 8.2. SignaJ Routing Mith Logc and Bit Lookup User-Defined Model Ports * Model-Wide peritiw* Operation» T&bi« Function* verification Subsystem utlititt 5irrwlinKBQChUbrary6.Q Copyright (c> 1990-2001 The MethVitork», Inc. Puc. 8.1. Окно Simulink library (Библиотека Simulink) Чтобы начать использование программы Simulink, выберите команду File ¦ New ¦ Model (Файл ¦ Создать ¦ Модель). При этом откроется пустое окно модели. Модель в программе Simulink создается путем копирования элементов, называемых блоками, из различных библиотек в окно модели. Мы объясним, как используется эта процедура, на примере модели однородного простого линейного дифференциального уравнения (ODE) u" + 2иг + 5и = 0, которое отображает работу излучателя затухающего гармонического сигнала.
Глава 8. Программа Simulink 149 File Edit View-; Help D ^ Commonly Uted Blocks: simulink/Commonly Used Blocks p; Simulink i-g Commonly Used Blocks i-- И Continuous Lgj] Discontinuities j-— ЕЯ Discrete I g*| Logic and Bit Operations j-ЙЗ Lookup Tables | ^ Math Operations Щ Model Verification r-E] Model-Wide Utilities ! re I |5jJ Ports & Subsystems B] Signal Attributes [5] Signal Routing Lg] Sinks j~-gfc3 Sources I—S User-Defined Functions ! !+)¦¦¦ Щ Additional Math & Discrete Ф Ш Communications Bbckset | Ш Control System Toobox | Ш Image Acquisition Toolbox I Щ Instrument Control Toolbox | Jg] Link for ModelSim ф- Ш Model Predictive Control Toolbox \Ь Ш Neural Network Toolbox j Ш OPC Toolbox В- У RF Blockset | Ml Real-Time Windows Target [+]¦¦ ffl Real-Time Workshop ф- Щ Real-Time Workshop Embedded Coder i ^ Report Generator SJS ЗД™1 Processing Blockset Й ¦ Ш Simulink Control Design ф-Н SimuSnk Extras ф Н Simulink Parameter Estimation 0 H Simulink Response Optimization | Щ SimuHnk Verification and Validation \ Щ Stateflow ф Ш System Identificatron Toobox И- Ш Vldeo and Ima9e Processing Bbckset Lt) Ml xPC Target Ready Puc. 8.2. Окно Simulink Library Browser (Обзор библиотеки Simulink) Сначала нам необходимо уяснить, как представить уравнение в виде, в котором программа Simulink сможет его моделировать. Вот один из таких способов. Так как временная переменная является постоянной (непрерывной), сначала мы открываем библиотеку Continuous (Постоянные), в системах UNIX - с помощью двойного щелчка на третьем слева значке в верхней строке (Рис. 8.1), а в системе Windows - либо щелкнув мышью на маленьком значке [+] слева от значка Continious (Постоянные) в правой верхней части окна (Рис. 8.2), или щелкнув мышью на маленьком значке слева от слова «Continious» (Постоянные) в левой части окна Simulink Library Browser (Обзор библиотеки Simulink). В системе Windows после открытия библиотека Continious (Постоянные) выглядит так (Рис. 8.3).
150 MATLAB Яе Edit View Hefc 'alive: Numerical derivative: du/di. i I Щ Commonly Used Blocks S Discontinuities -H Discrete - gp Logic and Bit Operations ...Щ Lookup Tables -S3 Math Operations ¦¦ jltl Model Verification Щ Model-Wide Utilities ... Щ Ports & Subsystems ¦¦- Щ Signal Attributes О Signal Routing ¦¦¦ Щ Sinks ЗЯ Sources j*fc] User-Defined Functions ffl¦¦¦ ?0 Additional Math & Discrete ¦ Communications Blockset HI Control System Toolbox HI Image Acquisition Toolbox И Instrument Control Toolbox 4 | " Ready Puc. 5.5. Библиотека Continlous (Постоянные) Обратите внимание, что и и u' получаются из ur и и" (соответственно) путем интегрирования. Поэтому перетащите с помощью мыши две копии блока Integrator (Интегратор) в окно модели. Программа Simulink автоматически присвоит второму блоку имя Integrator! (Интегратор 1), чтобы отличить его от первого блока с именем Integrator (Интегратор). Обратите внимание, что каждый блок Integrator (Интегратор) имеет входной и выходной порты. Подровняйте выходной порт блока Integrator (Интегратор) с входным портом блока IntegratoM (Интегратор 1) и соедините их стрелкой, используя левую кнопку мыши. Стрелка, соединяющая два блока, называется сигналом. Дважды щелкните мышью на этой стрелке, и появится небольшое текстовое поле, в которое вы можете ввести название ur. (Вы можете также щелкнуть правой кнопкой мыши на стрелке, выбрать команду Signal Properties... (Свойства сигнала) и ввести свое название в поле Signal Name (Название сигнала).) Способом, описанным выше, добавьте стрелку, входящую в блок Integrator (Интегратор) (представляет и"), и стрелку, выходящую из блока Integrator 1 (Интегратор 1) (представляет и). Эти стрелки еще не обеспечивают соединение с другими блокоми, поэтому программа Simulink отмечает их пунктирными линиями, чтобы напомнить вам, что они не являются полностью работоспособными. Идея состоит в том, что и получается путем интегрирования из и', аи' получается тем же путем из и". Ваше окно модели теперь должно выглядеть так, как изображено на рисунке ниже (Рис. 8.4).
Глава 8. Программа Slmullnk 151 Интегратор Интегратор1 Рис. 8.4. Первая стадия модели в программе Simulink Теперь нам необходимо использовать дифференциальное уравнение, которое можно записать в форме и" в -5и - 2иг. Нам необходимо добавить другие блоки, чтобы связать и", ввод первого блока Integrator (Интегратор), с и и и' соответственно этому уравнению. Для этой цели мы добавляем два блока Gain (Увеличение), которые выполняют умножение по константе, и один блок Sum (Сумма), используемый для сложения. Все они выбираются из библиотеки Math Operations (Математические операции) (седьмая сверху на Рис. 8.2 и первая во второй строке на Рис. 8.1). После их извлечения (тем же способом, что и блоки Integrator (Интегратор)) мы получим окно модели, которое выглядит так (Рис. 8.5). 1 s ¦к и' Р 1 s Интегратор Интегратор1 Увеличение 0 Увеличение1 Рис. 8.5. Вторая стадия модели в программе Simulink Нам необходимо вернуться назад и отредактировать свойства блоков Gain (Увеличение), чтобы изменить константы, на которые они умножаются, со значения по умолчанию 1 на -5 (блок Gain (Увеличение)) и -2 (блок Gaini (Увеличение 1)). Для этого по очереди щелкните мышью на каждом из блоков Gain (Увеличение). Откроется диалог Block Parameters (Параметры блока), в котором можно изменять параметры, как вам требуется. Далее, нам необходимо направить и', вывод первого блока Integrator (Интегратор), к порту ввода блока Galni (Увеличение 1). При этом возникает проблема, так как блок Integrator (Интегратор) имеет только один порт вывода, и он уже присоединен к следующему блоку. Поэтому нам необходимо познакомиться с разветвлением линий. Поместите указатель мыши на середине стрелки, соединяющей два блока Integrator (Интегратор), нажмите и не отпускайте клавишу ИCtrl I одной рукой, одновременно нажмите левую кнопку мыши другой рукой, и перетащите указатель мыши к порту ввода блока Gaini (Увеличение 1). Мы почти закончили, но нам нужен еще блок для просмотра вывода. Откройте библиотеку Sinks (Приемники) и перетащите копию блока Scope (Экран) в окно модели. С помощью разветвления линии соедините этот блок с линией, соединяющей блоки IntegratoM (Интегратор 1) и Gain (Увеличение). Здесь вам может понадобится переделать названия блоков (путем редактирования
152 MATLAB текста под каждым блоком), а также названия некоторых стрелок. В результате получится модель, показанная на рисунке ниже {Рис. 8.6). Интегратор Интегратор1 Увеличение гл Экран -2u* Увеличение1 Рис. 8.6. Модель для уравнения и" = -5и - 2ul в программе Simulink Теперь все готово для запуска процесса симуляции. Сначала следует сохранить модель, используя команду меню File ¦ Save as... (Файл ¦ Сохранить как). Модели можно присвоить имя dampedosc. (Программа MATLAB автоматически добавляет расширение файла .mdl, предназначенное для моделей.) Чтобы видеть, что происходит во время симуляции, дважды щелкните мышью на блоке Scope (Экран), чтобы открыть экран «осциллографа», на котором и будет изображаться как функция от f. Разумеется, необходимо также задать начальные условия; это можно сделать, дважды щелкнув мышью на блоках Integrator (Интегратор) и изменив строку Initial Condition (Начальное условие) в диалоге Block Parameters (Параметры блока). Например, предположим, что мы задаем начальное условие для ur (в первом блоке Integrator (Интегратор)), как значение 5, и условие для и (во втором блоке Integrator! (Интегратор 1)), как значение 1. Другими словами, мы решаем систему линейных уравнений и" + 2иг + 5и = О и@) = 1 и'@) = 5 которая имеет точное решение u(t) = Зе-t sinBt) + e-t cosBt) Перейдите в меню Simulation (Симуляция) и выберите команду Start (Запуск). В окне Scope (Экран) вы должны увидеть нечто похожее на то, что изображено на Рис. 8.7. Разумеется, это просто график функции Зе-t sinBt) + e-t cosBt). (Кстати, вам может понадобится изменить масштаб на вертикальной оси в окне Scope (Экран). Щелчок мышью на значке с изображением бинокля производит автоматическое перемасштабирование, а щелчок правой кнопкой мыши на вертикальной оси открывает меню Axes Properties... (Свойства осей), которое позволяет вам выбирать вручную минимальные и максимальные значения зависимой переменной.) Если необходимо, то можно легко вернуться обратно, изменить некоторые параметры и снова перезапустить симуляцию.
Глава 8. Программа Simulink 153 Рис. 8.7. Решение уравнения и" = -5и - 2и', и (О) и ' @) = 5 в окне Scope (Экран) 1, •/ Возможно, вы сочтете, что лучше полагаться на блок Derivative (Производная), чем на блок Integrator (Интегратор), для симуляции дифференциальных уравнений. Но у этого пути есть две отрицательные стороны: сложнее установить начальные условия, а также числовое дифференцирование менее надежно, чем числовое интегрирование. Наконец, предположим, что теперь требуется изучить неоднородное уравнение для принудительных колебаний, и" + 2u' + 5u = g (t), где g является принудительно заданным периодом. Все, что нам надо для этого сделать - это добавить другой блок к модели из библиотеки Sources (Источники). Щелкните мышью на черенке стрелки вверху модели, перемещаясь к первому блоку Integrator (Интегратор), и выберите команду меню Edit ¦ Cut (Редактирование ¦ Вырезать), чтобы удалить ее. Затем перетащите другой блок Sum (Сумма) (из библиотеки Math Operations (Математические операции)), поместите его перед первым блоком Integrator (Интегратор) и подведите подходящий источник к порту ввода блока Sum (Сумма). Например, если g(t) представляет «шум», перетащите блок Band-Limited White Noise (Белый шум с ограниченной полосой частот) из библиотеки Sourses (Источники) на модель и подключите все так, как показано на Рис. 8.8. -5u-2u" Интегратор Интегратор! Увеличение Экран -И-2 Белый шум с ограниченной полосой частот. Увеличение! Рис. 8.8. Модель уравнения и" = -5и - 2и ' + g(t) в программе Simulink
154 MATLAB Выходной сигнал этой исправленной модели (со значениями по умолчанию 0.1 для поля Noise power (Мощность шума) и 0.1 для поля Sample time (Эталонное время)) показан на рисунке (Рис. 8.9). Эффект шума в системе ясно различим в процессе симуляции. Рис. 8.9. Решение простого дифференциального уравнения шума в окне Scope (Экран) Пример проектирования Здесь вашему вниманию предоставляется более сложный пример, являющийся типичным для проектирования в программе Simulink. В нем рассматривается кран, используемый для погрузки морских контейнеров в порту. Этот кран схематически представлен на рисунке (Рис. 8.10). Рис. 8.10. Схема крана для погрузки контейнеров
Глава 8. Программа Simulink 155 Для упрощения допустим, что радиус шкивов и размер контейнера не учитываются и что шкив в верхней правой части может перемещаться горизонтально, гак чтобы оператор крана мог регулировать параметры w (разделение двух шкивов) и 1 (длина троса, удерживающего контейнер) как угодно. Точку отсчета мы размещаем на зафиксированном шкиве, так, чтобы на основе параметров w, 1 и 0 (угол отклонения троса от вертикали) контейнер находился в точке с координатами (x,y) = (w,O) + (lsin0,-lcos0) = (w+lsme,-lcose). (8.1) Нам необходимо смоделировать результат поднятия контейнера с земли в точке (wo,-lo), его перемещения и повторного размещения в точке (w1#-l0). В частности, необходимо контролировать поперечные колебания, так, чтобы качающийся контейнер не ударил что-либо или кого-либо. Для упрощения допустим, что единственными силами, воздействующими на контейнер, являются упругость троса (которая может изменяться во времени) и сила тяжести. (Например, мы не принимаем в расчет сопротивление воздуха.) Давайте произведем и дальнейшее упрощение: допустим, что оператор крана перемещает контейнер в три этапа, где на первом этапе контейнер поднимается вертикально вверх, на втором этапе величина 1 (длина троса, соединяющего контейнер с подвижным шкивом) сохраняется постоянной, и на третьем этапе контейнер опускается вниз. Этапы 1 и 3 не особенно интересны, поэтому мы сосредоточимся на этапе 2; это означает допущение, что величина 1 сохраняется постоянной, а величина w является функцией времени, выбираемого оператором крана, с начальным значением w0 и конечным значением wj,. Пусть хп будет массой контейнера. Чтобы получить уравнения движения, отметьте, что кинетическая энергия К и потенциальная энергия силы тяжести V контейнера задаются следующим образом: к=у (С*'J Ну'J =j((w'+i(cosewJ +№пв)в'J) =—((w'J +l\0'J +2lw'(cosO)e') (8.2) V = mgy = -mgl cos в. В лагранжевой механике уравнение движения выглядит так: dL = d dL дв ~ dt дв' где функция Лагранжа есть L ¦ К - V, поэтому (после деления на постоянный множитель т) мы получаем
156 MATLAB -gl sin в - lw\t){sm в)& =—(l2в' + lw\t) cos 9) dt = I2 0"+lw\t) cos 0 ^ /w'(O(sin &)&, или (после деления на L 2) 1 2 в" + -w"(t)cos0 + — sin0 = 0, (8.3) которое представляет собой обыкновенное уравнение маятника (нелинейное уравнение маятника рассматривается в главе 10) с дополнительным элементом, включающим w"(t), горизонтальным ускорением крана. Теперь мы можем построить модель программы Simulink для нашего крана. Можно поэкспериментировать с различными возможностями для w(t) и посмотреть, какой это окажет эффект на величину колебания троса, 0 (t). В качестве единиц измерения воспользуемся метрами и секундами и примем значения g =9.81 м/с2, 1 = 5 м, w0 = 0 и Wj. = 10 м. Время, необходимое для перемещения контейнера, должно быть порядка нескольких минут, или, скажем, 200 секунд. Таким образом, нам необходимо, чтобы w была непрерывной функцией, предпочтительно с непрерывной второй производной (так как сила мотора, вращающего шкив, пропорциональна w" и должна быть непрерывной временной функцией), со значениями w@) = 0 и w B00) = 10. Такая функция получается следующим образом: w(t) = 5+a(t -100)+b(t-WOY+c(t-\OOM. Этим обеспечивается равенство wA00) = 5, и график w имеет неравную симметрию вокруг точки A00, 5). Фактически, так как только нечетные степени от t - 100 появляются в формуле для w(t) - 5, то, следовательно, wA00 + t) - 5 = -(wA00 - t) -5), и, при условии t = 0, мы видим, что 2w( 100) = 10 или wA00) = 5. Введя t = 100 в это уравнение, получаем wB00) - 5 = -w@) + 5, а отсюда получаем wB00) = 10, если w@) = 0. Таким образом, мы вычисляем коэффициенты a, b и с, чтобы получилось равенство w@) = wr@) = w' ' @) = 0. Ниже представлено решение, полученное при использовании программы MATLAB: >> syms t a b с » w = 5 + a*(t-100) + b*(t-100)A3 + с*(t-100)A5; >> wO = subs(w, t# 0); » wl = subs(diff(w# t)# t# 0); » w2 = subs(di??(w, t, 2), t, 0); >> [aa, bb, cc] = solve(w0/ wl, w2); >> w = subs(w, [a, b, c], [aa, bb, cc]) w =
Глава 8. Программа Simulink 157 -35/8+3/32*t-l/160000*(t-100)"З+ЗПбООООООООО*(t-100) График этой функции показан на Рис. 8.11. w(t) 200 Рис. 8.11. График функции w(t) В этой функции формула для w" (t) будет такой: » diff(w# t, 2) ans = -3/80000*t+3/800+3/800000000*(t-100)Л3 Рис. 8.12. Модель по изучению движения крана в программе Simulink Модель по изучению этой системы представлена на Рис. 8.12. Давайте рассмотрим, как эта модель работает и как ее собирать (монтировать). Начнем с того, что перепишем уравнение 8.3 в приведенной ниже форме:
158 MATLAB в" = -^- sin в - - w"(t) cos 0. I I Таким образом, мы представляем 9" в виде суммы двух элементов, каждый со знаком минус впереди, которые собираются вместе в блоке Add (Добавление). (Кстати, нет никакой разницы между блоками Add (Добавление) и Sum (Сложение), за исключением формы представляющих их значков.) Сигнал (соединительная линия), представляющий 9", входит в блок Integrator^ (Интегратор 1) в левой верхней части модели, а сигнал, выходящий из второго блока Integrator (Интегратор), представляет 9. Блок Clock (Время) выводит значение t, которое идет в блок Function (Функция) (из библиотеки User-Defined Functions (Функции, заданные пользователем)), используемый для вычисления w" (t). Блоки Product (Произведение) и Trigonometric Function (Тригонометрическая функция), оба из библиотеки Math Operations (Математические операции), дополнительных пояснений не требуют. Присутствуют еще два блока Gain (Увеличение), тоже из библиотеки Math Operations (Математические операции), используемые для умножения sinG и cos9 на константы g/L и 1/L соответственно. Для удобства мы переименовали эти два блока, чтобы показать, который из них каким является. Чтобы переименовать блок, щелкните мышью на названии под блоком, и название будет заключено в серое поле. Затем вы можете стереть старое название и вставить новое. Как и в примере в предыдущем разделе, блоки Gain (Увеличение) необходимо настраивать для соответствующих констант с помощью диалога Block Parameters (Параметры блока). Этот диалог можно похожим образом использовать для блока Trigonometric Functioni (Тригонометрическая функция 1), чтобы переключить функцию синуса (установлена по умолчанию) на функцию косинуса, которая нам нужна. Так как кран начинает движение из состояния покоя (с начальными условиями 9@) = 9Г = 0, нам не требуется изменять установленное по умолчанию начальное условие, равное 0, в каждом блоке Integrator (Интегратор). Необходимо настроить блок Function (Функция) путем вставки формулы для w"(u). (Здесь программа Simulink категорически требует, чтобы независимая переменная называлась и, а не t.) Наконец, необходимо щелкнуть мышью на меню Simulation (Симуляция), чтобы изменить максимальное значение t, по умолчанию равное 5, на значение 200, необходимое для этой задачи. Результат запуска симуляции (после того как вы щелкнете мышью на значке с изображением бинокля, чтобы изменить масштаб изображения) отображается в окне Scope (Экран), как показано на рисунке ниже (Рис. 8.13). Если вы посмотрите на легенду (сопроводительную информацию) на изображении, вы увидите, что максимальное значение 9 будет порядка 2x10-4 радиан, что очень мало, даже при умножении на длину троса 1 = 5м. Из этого мы делаем вывод, что колебания контейнера не составят серьезной проблемы в данном случае.
Глава 8. Программа Simulink 159 Рис. 8.13. Вывод результатов колебаний крана в окне Scope (Экран) Ht Взаимодействие с рабочей областью Примеров, которые мы рассмотрели, вполне достаточно, чтобы дать вам представление о том, как использовать программу Simulink в качестве автономного инструмента моделирования. Но часть возможностей программы Simulink зависит от способа ее объединения с программой MATLAB. Например, можно запустить модель Simulink из М-файла или произвести с помощью MATLAB дальнейшую обработку результатов вывода. В этом разделе мы рассмотрим некоторые важные команды для объединения программ Simulink и MATLAB. Начнем с практического примера. Предположим, что вы хотите пересчитать формулу для w(t) в примере с краном, так, чтобы w достигла значения 10 при t = 20 вместо t = 200. Другими словами, нам необходимо сохранить форму w(t), такую, как показано на Рис. 8.11, но сжать шкалу горизонтальной оси в 10 раз. Какими же теперь будут колебания троса, если кран станет перемещать контейнер с большей скоростью? Станет ли этот процесс более опасным? Чтобы ответить на этот вопрос, мы заменим прежнее выражение w (t) следующим образом: >> w я simplify (subs (w, t, 10*t)) w = l/80*t/43+3/160000*t/45-3/3200*t/44 Также мы заменим прежнее выражение w" (t) вот так: » diff(w, t, 2)
160 MATLAB ans = 3/40*t+3/8000*t/43-9/800*t/42 Первое, что нам необходимо сделать, это внести изменения в параметры блока, озаглавленного f (u) на Рис. 8.12. Это можно сделать с помощью команд get_param и set_param из командной строки или из М-файла (а не с помощью диалога Block Parameters (Параметры блока)). Это особенно удобно, если вам требуется запускать симуляцию много раз с различными значениями параметров. Иногда помогает использование команд gcs («get current system» - найти текущую систему) и f ind_system для поиска названий важных блоков. Ниже представлен пример, основанный на предположении, что мы уже открыли модель, отображенную на Рис. 8.12г. » gcs ans = crane >> find_system(gcs, 'Type', 'block') ans = 'crane/1/ /1' 'crane/Add' 'crane/Clock' ' crane/Integrator' 'crane/Integrator 1' 'crane/Product' 'crane/Scope' 'crane/Trigonometric Function' 'crane/Trigonometric Function 1' 'crane/g/ /1' 'crane/w" ' Это дает нам названия всех блоков; в данном случае нам необходимо изменить параметры блока с названием 'crane/w//r. (Если бы нам понадобилось изменить длину троса, нам также пришлось бы изменить параметры блоков ' crane/1/ /1' и ' crane/g/ /lr.) Чтобы увидеть текущее значение 'Ехрг' этого блока, который кодирует функцию w" (t), введите следующее:
"лава 8. Программа Simulink 161 > > get_param ( ' crane/w" ', * Expr') ans = -3 /80000*u+3/800 + 3/800000000*(u-100)Л3 Гаким образом, мы можем повторно запустить это выражение следующим способом: >> set_param( 'crane/w"' # 'Expr' й . . . '3/40*u+3/8000*uA3-9/800*uA2') Чтобы перезапустить модель, вместо команды меню Simulation ¦ Start (Симуляция ¦ Запуск) мы можем использовать команду sim в командной строке или в М-файле. Простейшая форма этой команды просто запускает модель с существующими параметрами. Но эту команду можно также использовать для задания временного интервала и вывести результаты в рабочую область. Например, в нашей ситуации мы могли бы ввести следующее: >> [t, theta] = sim(rcraner, [0, 20]); \ затем можно было бы ввести код » plot(t/ theta) чтобы начертить результаты, представленные на Рис. 8.14. Здесь кривая, которая заканчивается в верхней части, представляет 0(t), а другая кривая пред- :тавляет 9 ' (t). -0.025 Рис. 8.14. Чертеж кривых Q(t) и Q'(t) для исправленной модели крана Или, чтобы продублировать возможное изображение в окне Scope (Экран), мы можем заменить команду plot на simplot (Рис, 8.15): » simplot(t, theta(:,l)) -1605
162 MATLAE Рис. 8.15. Чертеж кривой 9 (t) для исправленной модели крана в окне Scope (Экран) |/ Кстати, если вы создаете изображение с помощью команды simplot, оно все гда отображается в окне изображения таким, как на Рис. 8.15, светлой линией на черном фоне. Но если вы распечатываете это изображение (на принтере или в файл), оно иногда (в зависимости от установок по умолчанию) можег отображаться с инверсными цветами, то есть линия чертежа будет черной, « фон - белым. Чтобы отменить эту цветовую инверсию, вам необходимо вста вить команду >> set(gcf, 'InvertHardCopy', roffr) перед выполнением команды print. Результат нашего анализа показывает, что, если морской контейнер перемещает ся за 20 секунд вместо 200, то колебания составляют порядка 0.02 радиана. Такт образом, контейнер будет раскачиваться в диапазоне 0.1 метра, или 10 см, чт< является вполне приемлемым. А вот что произойдет, если контейнер будет пере мещаться всего лишь за 2 секунды, попробуйте решить сами.
ГЛАВА 9. Графический интерфейс пользователя С помощью программы MATLAB вы можете создать свой собственный графический интерфейс пользователя - GUI (от англ. Graphical User Interface - Графический интерфейс пользователя), состоящий из окна изображения, содержащего меню, кнопки, текст, графику и другие элементы, с которыми пользователь может работать в интерактивном режиме, используя мышь и клавиатуру. Создание GUI (Графический интерфейс пользователя) включает в себя два основных этапа: во-первых, организацию расположения элементов, во-вторых, запись функций обратного вызова, которые выполняют необходимые операции, когда пользователь выбирает различные параметры. Планировка GUI и инструмент GUIDE Определение местоположения и свойств различных объектов GUI (Графический интерфейс пользователя) можно осуществлять с помощью команд uicontrol, uimenu и ui с on text menu в М-файле. Программа MATLAB предоставляет также интерактивный инструмент под названием GUIDE (Graphical User Interface Development Environment - Среда разработки графического интерфейса пользователя), который значительно упрощает задачу построения GUI (Графический интерфейс пользователя). В этой главе мы рассмотрим, как начать процесс создания GUI (Графический интерфейс пользователя) с помощью инструмента GUIDE (Среда разработки графического интерфейса пользователя) той версии, которая включена в программу MATLAB 7. Эта версия располагает расширенными возможностями по сравнению с более ранними версиями. Версия GUIDE (Среда разработки графического интерфейса пользователя) в программе MATLAB 6 примерно такая же, но некоторые элементы и параметры меню отличаются или отсутствуют. |/ Некоторым недостатком инструмента GUIDE (Среда разработки графического интерфейса пользователя) является то, что он создает графический интерфейс с помощью новых команд, появившихся только в версии MATLAB 7, и сохраняет план GUI (Графический интерфейс пользователя) в двоичном файле с расширением .fig. Если вы хотите создать простой и надежный интерфейс, который смогут использовать различные пользователи в различных версиях программы MATLAB, вам лучше будет не записывать GUI (Графический интерфейс пользователя) с нуля в качестве М-файла. Чтобы открыть инструмент GUIDE (Среда разработки графического интерфейса пользователя), выберите команду File ¦ New ¦ GUI (Файл ¦ Создать ¦ GUI) в меню Рабочего стола или введите команду guide в окне Command Window (Командное окно). На экране будет отображен диалог GUIDE Quick Start (Быстрый старт GIUDE), показанный на Рис. 9.1.
164 MATLAB Обратите внимание, что в верхней части есть две вкладки. Левая вкладка, под названием Create New GUI (Создать новый интерфейс), открывается по умолчанию. Вы можете начать, выбрав какой-либо из различных типов GUI (Графический интерфейс пользователя) слева. При этом откроется модуль Layout Editor (Редактор планировки), в котором вы будете создавать внешний вид вашего интерфейса. Для соответствия с описанными здесь примерами мы предположим, что вы выбрали третий элемент, GUI with Axes and Menu (Интерфейс с осями и меню). Create NewOUf j Open Existing GUI | GUIDE templates rPre GUI with Uicontrols . GUI with Axes and Menu Modal Question Dialog BLANK !~~ Save on startup as: JQAPrapram Fi!esU$ATLAB71*vorttun№;erf ?4i Browse Hel Puc. 9.1. Диалог GUIDE Quick Start (Быстрый старт GIUDE) Модуль Layout Editor (Редактор планировки) будет выглядеть, как на Рис. 9.2. (Эт< версия отображается в системах Windows; в системах UNIX или Linux не будет ото бражаться самая нижняя кнопка, предназначенная для отображения элементо! ActiveX.) Не ?Ш Vtew Layout Tools Hdp d Puc. 9.2. Модуль Layout Editor (Редактор планировки) Предположим, что вам требуется создать GUI (Графический интерфейс пользо вателя), который будет принимать графические команды программы MATLAB i качестве ввода, отображать вывод результатов и иметь кнопки для внесения раз личных изменений в отображение выводимых результатов.
Глава 9. Графический интерфейс пользователя 165 Кнопки слева в окне модуля Layout Editor (Редактор планировки) используются Оля вставки различных типов объектов. Построение GUI (Графический интерфейс пользователя) производится следующим способом: вы щелкаете мышью на эдной из кнопок, затем перемещаете указатель мыши в требуемое место на сетке и щелкаете мышью снова, чтобы закрепить там объект. Чтобы увидеть, какому гипу объектов соответствует каждая кнопка, перемещайте указатель мыши поверх кнопок, но не щелкайте; над каждой кнопкой будет отображаться желтое поле с названием кнопки. После того как вы разместите объект на сетке, вы можете щелкнуть мышью на середине объекта и перетащить его (перемещать мышь, удерживая нажатой левую кнопку мыши), или щелкнуть мышью на одном из углов, чтобы изменить размер объекта. После размещения нескольких объектов вы можете выделить их все вместе, щелкнув мышью и перетащив указатель мыши по фоновой сетке так, чтобы заключить эти объекты в прямоугольник. Затем вы можете мышью переместить объекты одним блоком или выровнять их, выбрав команду меню Tools ¦ Align Objects... (Инструменты ¦ Выровнять объекты). Для изменения свойств объекта, таких как цвет, текст внутри объекта и т.д., вам необходимо открыть окно Property Inspector (Инспектор свойств). Для этого слезет дважды щелкнуть мышью на объекте или выбрать команду меню View ¦ Property Inspector (Вид ¦ Инспектор свойств), а затем с помощью левой кнопки мыши выделить объект, который хотите изменить. Вы можете оставить окно Property Inspector (Инспектор свойств) открытым на протяжении всего процесса работы с 3UIDE (Среда разработки графического интерфейса пользователя) и переключаться между ним и модулем Layout Editor (Редактор планировки). Рис. 9.3. Модуль Layout Editor (Редактор планировки) с дизайном интерфейса типа Plot GUI (Чертежный интерфейс)
166 MATLAl На Рис. 9.3 показано, как выглядит окно модуля Layout Editor (Редактор пла нировки) после размещения нескольких объектов и настройки их свой ств. Давайте рассмотрим создание объектов, составляющих графически! интерфейс. Два поля сверху, равно как и поле с названием Set axis scaling (Задать масшта! осей), являются полями постоянного текста, с которыми пользователь интер фейса не сможет манипулировать. Чтобы создать каждое из них, мы сначал щелкнули мышью на кнопке Static Text (Постоянный текст) (одна из тех, что еле ва от сетки, с надписью «ТХТ»), а затем щелкнули мышью в том месте на сетке где требуется добавить текст. Далее, чтобы вставить в поле текст, мы открыл] диалог Property Inspector (Инспектор свойств) и щелкнули на квадратной кнопк< рядом с надписью String (Строка); при этом открывается новое окно, которо< содержит редактируемый текст по умолчанию. Наконец, мы изменили размерь каждого поля соответственно объему текста (щелкнуть мышью на углу и перета щить указатель). Кнопки с названиями Plot it! (Начертить), Change axis limits (Изменить предель осей) и Clear figure (Очистить изображение) являются объектами типа Push Buttoi (Нажми кнопку). Эти кнопки создаются путем использования кнопки с надпись» «ОК». Чтобы придать этим кнопкам одинаковый размер, мы сначала создали ол ну из них, а затем, после назначения размера, дважды ее дублировали, щелка; правой кнопкой мыши на уже существующем объекте и выбирая команду Duplicat (Дублировать). Затем мы переместили кнопки на различные позиции и изме нили их текст тем же способом, как это делается для полей Static Text (Статич ный текст). Пустое поле в верхней части сетки - это поле Edit Text (Редактирование текста) которое позволяет пользователю вводить текст. Мы создали его с помощьн кнопки с надписью «EDIT», а затем убрали текст по умолчанию, как делали эт< ранее. Под полем Edit Text (Редактирование текста) находится большое поле Axei (Оси), похожее на поле, отображенное на Рис. 9.2, но с измененным размером Справа внизу находится кнопка Hold is OFF (Захват отключен), являющаяа кнопкой типа Toggle Button (Кнопка-переключатель), которая создается с помо щью кнопки с надписью «TGL». Для переключающих (включить-выключить команд вы могли бы также использовать Radio Button (Селективная кнопка) ил* Checkbox (Поле с флажком), которые обозначаются, соответственно, кнопками < изображениями точки и флажка. Наконец, поле справа, с надписью «equal» - эк Popup Menu (Открывающееся меню), кнопка которого в модуле Layout Editoi (Редактор планировки) располагается справа под кнопкой Edit Text (Редакти рование текста). Объекты Popup Menu (Открывающееся меню) и Listbox (Поле списка) позволяют предоставить пользователю возможность выбора среду нескольких параметров.
Глава 9. Графический интерфейс пользователя 167 Мы переместили, изменили размер и в большинстве случаев изменили свойства каждого объекта описанным выше способом. В случае с Popup Menu (Открывающееся меню), после того как была выбрана кнопка String (Строка) в Property Inspector (Инспектор свойств), мы ввели в появившееся окно три слова в три отдельные строки: equal, normal и square. Использование нескольких строк необходимо, чтобы дать пользователю несколько вариантов выбора в объектах Popup Menu (Открывающееся меню) и Listbox (Поле списка). \/ Кроме заполнения вашего интерфейса рассмотренными выше объектами вы можете создать строку меню, используя Menu Editor (Редактор меню), который можно открыть, выбрав команду меню Tools ¦ Menu Editor (Инструменты ¦ Редактор меню). Вы можете также использовать Menu Editor (Редактор меню), чтобы создавать контекстные меню для объекта; это меню, которое появляется, когда вы щелкаете на объекте правой кнопкой мыши. Чтобы научиться пользоваться модулем Menu Editor (Редактор меню), обратитесь к онлайновой документации для GUIDE (Среда разработки графического интерфейса пользователя). Мы также присвоили нашему интерфейсу название, которое будет отображаться в строке заголовка. Мы щелкнули мышью на фоновой сетке в Layout Editor (Редактор планировки), чтобы выделить весь GUI (Графический интерфейс пользователя) (подобно объекту внутри него), и перешли в Property Inspector (Инспектор свойств). Там мы изменили текст в поле «Name» (Название) с Untitled (Безымянный) на Simple Plot GUI (Простой чертежный интерфейс). Сохранение и запуск GUI Чтобы сохранить GUI (Графический интерфейс пользователя), выберите команду меню File ¦ Save As... (Файл ¦ Сохранить как). Введите имя файла для вашего интерфейса без какого-либо расширения; для интерфейса, рассмотренного выше, мы выбираем имя plotgui. В процессе сохранения создаются два файла, М-файл и двоичный файл с расширением .fig, таким образом, в нашем случае результирующие файлы будут иметь имена plotgui.m и plotgui.fig. Когда вы сохраняете GUI (Графический интерфейс пользователя) в первый раз, М-файл для этого интерфейса отображается в отдельном окне модуля Editor (Редактор). Как и зачем модифицируется этот файл, мы рассмотрим в следующем разделе. ?> Инструкции в этом и следующем разделе излагаются с предположением, что в GUI Options (Параметры интерфейса) приняты настройки по умолчанию, наличие которых вы можете проверить, запустив GUIDE (Среда разработки графического интерфейса пользователя), как рассмотрено выше. С другой стороны, вы можете получить к ним доступ через меню Tools (Инструменты). В частности, мы предполагаем, что будут выбраны параметры Generate FIG-file and M-file (Создавать FIG-файл и М-файл), Generate callback function prototypes (Создавать прототипы возвратной функции) и GUI allows only one instance to run (Запускать только одну копию интерфейса).
168 MATLAB Когда процесс сохранения завершен, вы можете запустить GUI (Графический интерфейс пользователя) в окне Command Window (Командное окно), введя его имя, в нашем случае plotgui, причем не важно, запущен или нет GUIDE (Среда разработки графического интерфейса пользователя). Оба файла, с расширениями .fig и .т, должны находиться в вашем текущем каталоге или указаны в пути программы MATLAB. Вы можете также запустить интерфейс из модуля Layout Editor (Редактор планировки) с помощью сочетания клавиш II Ctrl Ни I. или выбрав команду меню Tools ¦ Run (Инструменты ¦ Запуск). Копия GUI (Графический интерфейс пользователя) будет отображена в отдельном окне, без всех меню и кнопок модуля Layout Editor (Редактор планировки). (Если вы добавили новые объекты с тех пор, как последний раз сохраняли или активировали GUI (Графический интерфейс пользователя), то ассоциированный с интерфейсом М-файл будет также выведен на передний план.) На Рис. 9.4 показано, как выглядит активизированный GUI (Графический интерфейс пользователя), созданный нами ранее. Изображение в координатном окне будет рассмотрено в разделе GUI Callback Functions (Возвратные функции GUI). Туре а МейаЬ piodins command here Then cfcck fwre: Plot it! Change axis tomtr Set axis scaling Gear figure Рис. 9.4. Активизированный интерфейс Simple Plot GUI Обратите внимание, что это отображение GUI (Графический интерфейс пользователя) немного отличается от того, которое мы видим в окне GUIDE (Среда разработки графического интерфейса пользователя); в частности, может отличаться размер шрифта. По этой причине вам может понадобиться вернуться в окно GUIDE (Среда разработки графического интерфейса пользователя) после активации GUI (Графический интерфейс пользователя) и изменить размер некоторых объектов. Внесенные вами изменения не будут сразу отображены в активном GUI (Графический интерфейс пользователя); чтобы увидеть результат произведенных изменений, необходимо повторно запустить GUI (Графический интерфейс пользователя).
"лава 9. Графический интерфейс пользователя 169 Эбъекты, которые вы создаете в модуле Layout Editor (Редактор планировки), шертны в этом окне. Вы не можете вводить текст в поле Edit Text (Редактирование текста), не можете видеть дополнительных параметров при щелчке мышью яа Popup Menu (Открывающееся меню) и т.д. Но в активном окне GUI (Графиче- :кий интерфейс пользователя) объекты типа Toggle Button (Переключатель) и Popup Menu (Открывающееся меню) будут реагировать на щелчки мышью. Однако они не будут в действительности выполнять какие-либо операции, пока вы не запишете возвратную функцию для каждого из них. Возвратные функции GUI Когда вы готовы к созданию возвратной функции для определенного объекта, убедитесь, что вы сохранили свой GUI (Графический интерфейс пользователя). Затем посмотрите в Property Inspector (Инспектор свойств) для объекта в модуле Layout Editor (Редактор планировки), в поле Tag (Тег) вы увидите тег (условное имя) объекта, которым он идентифицирован в М-файле, связанном с вашим GUI (Графический интерфейс пользователя). Откройте М-файл в окне модуля Editor (Редактор) (если он не открыт) и перейдите к разделу М-файла, связанному с этим тегом. Вы увидите небольшой текстовый блок, который выглядит подобно приведенному ниже: уо Executes on button press in pushbuttonl. function pushbuttonl__Callback(hObject, eventdata, handles) h hObject handle to pushbutton2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see 6UIDATA) Все что теперь требуется сделать для «оживления» функции Push Button (Нажать кнопку) - это добавить команды, которые должны быть выполнены, когда пользователь щелкнет мышью на кнопке. Разумеется, вам также необходимо сохранить М-файл; вы можете сделать это обычным способом в модуле Editor (Редактор) или путем активации GUI (Графический интерфейс пользователя) из модуля Layout Editor (Редактор планировки). Каждый раз при сохранении или активации GUI (Графический интерфейс пользователя) блок из пяти строк, похожий на представленный выше, автоматически добавляется к М-файлу интерфейса. Это делается для любых новых объектов или элементов меню, которые вы добавляете в GUI (Графический интерфейс пользователя) и которые должны иметь возвратные функции. Во многих случаях, после того как вы в достаточной степени настроите свойства объекта, GUIDE (Среда разработки графического интерфейса пользователя) может вставлять некоторые команды в М-файл автоматически, но вам может понадобиться модифицировать их. Например, GUIDE (Среда* разработки графического интерфейса пользователя) вставляет в М-файл раздел, который начинается кодом
170 MATLAB % Execute just before plotgui is made visible. function plotgui_OpeningFcn (hobject, eventdata,handles,varargin) % This function has no output args, see OutputFen. и включает в себя строки % This sets up the initial plot - only do when we are invisible % so window can get raised using plotgui. if strcxnp(get(hObject, 'Visible' ), 'off') plot(randE)); end Это тот раздел М-файла, который отвечает за «случайные линии», которые вы видите в окне координат (Рис. 9.4). Если бы мы убрали эти строки или изменили их, GUI (Графический интерфейс пользователя) загрузился бы с совершенно другим изображением или не загрузил бы вообще никакого изображения. Для Popup Menu (Открывающееся меню) с правой стороны GUI (Графический интерфейс пользователя) мы вставляем следующие строки в возвратную функцию (модифицированную из шаблона, который поставляется с основным GUI (Графический интерфейс пользователя) (Рис. 9.2)). popup_sell_index = get(hObject, 'Value'); switch popup_sell_index case 1 axis equal case 2 axis normal case 3 axis square end Каждый раз, когда пользователь GUI (Графический интерфейс пользователя) выбирает элемент из открывающегося меню, программа MATLAB присваивает свойству объекта Value (Значение) выбранный номер строки и запускает соответствующую возвратную функцию. Подобно тому, как это было рассмотрено в главе 5, вы можете использовать команду get, чтобы получить текущие настройки свойства графического объекта. При использовании возвратных шаблонов, предоставляемых инструментом GUIDE (Среда разработки графического интерфейса пользователя) (как было описано), переменная hObject будет содержать управляющий элемент (требуемый первый аргумент команды get и set) для соответствующего объекта. (Если вы используете другой метод записи возвратных функций, вы можете применить в программе MATLAB команду gebo вместо команды
лава 9. Графический интерфейс пользователя 171 Object.) Для нашего образца интерфейса строка 1 в Popup Menu (Открываются меню) содержит значение «equal», и, если пользователь выбирает строку 1, озвратная функция запускает команду axis equal; то же происходит и с дру- ими строками. ' Вы могли заметить, что Popup Menu (Открывающееся меню) на Рис. 9.4 содержит значение «normal», а не «equal», как на Рис. 9.3; это потому, что мы назначили свойству Value (Значение) значение 2 при создании GUI (Графический интерфейс пользователя) с использованием Property Inspector (Инспектор свойств). В данном случае вы можете сделать выбранным по умолчанию не второй, а любой другой элемент в Popup Menu (Открывающееся меню) или Listbox (Поле списка). (ля Push Button (Нажать кнопку) с названием Plot it! (Начертить) мы записали ледующую возвратную функцию: tet(handles.figurel, 'HandleVisibility', 'callback'); ival (get(handles.editl, 'String')) 1десь handles,figure 1 и handles.editl являются управляющими элемента- ги для всего окна интерфейса и для поля Edit Text (Редактирование текста) соответственно. Эти переменные тоже предоставляются возвратными шаблонами в illlDE (Среда разработки графического интерфейса пользователя), и, если вы не [спользуете эту возможность, вы можете создать нужные управляющие элементы помощью команд gcbf и f indobj (gcbf, 'Tag', 'editl') соответственно, вторая строка возвратной функции (см. выше) использует команду get для поис- :а текста в поле Edit Text (Редактирование текста), а затем запускает команду с юмощью eval. Первая строка использует команду set, чтобы сделать окно ин- ерфейса доступным для графических команд, используемых в возвратных функ- *иях; если бы это не было сделано, то команда рисования, запущенная второй трокой, открыла бы отдельное окно изображения. t Мы могли бы также ассоциировать возвратную функцию с полем Edit Text (Редактирование текста); эта функция запускалась бы каждый раз при нажатии пользователем клавиши llEnterl после введения текста в поле. Возвратная функция eval (get (hObject, 'String')) запустит только что введенную команду, представляя альтернативу кнопке Plot It! (Начертить). / Другой способ активировать рисование изображения в окне GUI (Графический интерфейс пользователя) - это выбрать команду меню Tools ¦ GUI Options (Инструменты ¦ Параметры GUI) в модуле Layout Editor (Редактор планировки) и внутри появившегося окна изменить параметр Command-line accessibility (Доступность командной строки) со значения Callback (Возврат) на On (Включено). При этом могут возникнуть трудности при введении пользователем команд рисования изображения в окне Command Window (Командное окно) для воздействия на окно GUI (Графический интерфейс пользователя). Более безопасно будет в параметре Command-line accessibility (Доступность командной строки) оставить значение Callback (Возврат). С такой настройкой приведенная ниже строка
172 MATLAB set(handles.figure1, 'HandleVisibi1ity', 'callback'); в возвратных функциях становится необязательной. Однако мы рекомендуем оставлять эту строку в возвратных функциях в случае, если вы решите изменить параметр Command-line accessibility (Доступность командной строки) позднее. В примере plotgui из предыдущего раздела есть один момент, где мы использовали существующую команду MATLAB в качестве возвратной функции. Для элемента Push Button (Нажать кнопку) под названием Change axis limits (Изменить пределы осей) мы просто ввели команду axlixndlg в возвратную функцию в файле plotgui.m. Эта команда открывает диалог, который позволяет пользователю вводить значения для диапазонов на осях х и у. В программе MATLAB существует несколько диалогов, которые вы можете использовать как в качестве возвратных функций, так и в качестве обыкновенных М-файлов. Например, вы можете использовать команду input dig вместо команды input. Чтобы ознакомиться с информацией по доступным диалогам, введите команду help uitools. Ниже представлена возвратная функция для элемента Push Button (Нажать кнопку) под названием Clear figure (Очистить изображение). set (handles, edit I, 'String', "); set (handles, figure 1, ' Handle Vi s ibi 1 i ty', 'callback') ; cla reset Первая строка очищает текст в поле Edit Text (Редактирование текста), а последняя строка очищает поле Axes (Оси) в окне GUI (Графический интерфейс пользователя). (Если ваш GUI (Графический интерфейс пользователя) содержит более одного поля Axes (Оси), вы можете использовать команду axes для выбора требуемого в данный момент поля в каждой из ваших возвратных функций.) Мы использовали приведенную ниже возвратную функцию для элемента Toggle Button (Кнопка-переключатель) под названием Hold is OFF (Захват отключен): set (handles. figurel, 'HandleVisibility' , 'callback') ; if get(hObject# 'Value') hold on set(hObject, 'String', 'Hold is ON'); else hold off set(hObject, 'String', 'Hold is OFF'); end Мы получаем свойство Value (Значение) элемента Toggle Button (Кнопка- переключатель) таким же способом, как и в приведенной выше возвратной функции для элемента Popup Menu (Открывающееся меню). Но для элемента Toggle Button (Кнопка-переключатель) это значение равно либо 0, если кнопка в
Глава 9. Графический интерфейс пользователя 173 состоянии out (выключена) (по умолчанию), либо 1, если кнопка в состоянии in (включена). (Элементы Radio Button (Переключатель) и Checkbox (Поле с флажком) также имеют свойство Value (Значение) с показателями 0 и 1.) Когда пользователь в первый раз активирует элемент Toggle Button (Кнопка- переключатель), значение приравнивается к 1, таким образом, возвратная функция (см. выше) запускает команду hold on и переназначает строку, отображаемую на элементе Toggle Button (Кнопка-переключатель), чтобы отразить изменение. При следующем нажатии кнопки пользователем эти операции повторяются в обратную сторону. Наконец, с объектом графического интерфейса вы можете также ассоциировать вариант возвратной функции под названием Button Down Fen (Нажатая кнопка). Такая функция начнется следующим образом % Executes on mouse press over axes background. function axesl_ ButtonDownFcn(hObject, eventdata, handles) и будет запущена, когда пользователь щелкнет мышью в окне координат (осей), или если щелкнет правой кнопкой мыши на таких объектах, как Push Button (Нажать кнопку) (в качестве противопоставления левой кнопке мыши для вызова возвратных функций). Чтобы создать такую функцию, вы можете щелкнуть правой кнопкой мыши на объекте в окне модуля Layout Editor (Редактор планировки) и выбрать команду View Callbacks ¦ ButtonDownFcn (Показать возвратные ¦ Нажатая кнопка). Вы можете точно также ассоциировать функции с некоторыми другими типами пользовательских событий (задач); чтобы узнать об этом больше, обратитесь к онлайновой документации или экспериментируйте, щелкая правой кнопкой мыши на различных объектах и на разметочной сетке позади них в окне модуля Layout Editor (Редактор планировки).
ГЛАВА 10. Прикладные задачи В этой главе мы познакомим вас с примерами, которые показывают, как можно применять среду MATLAB для решения задач из различных дисциплин. Большинство примеров представлены в виде М-файлов для среды MATLAB. Эти примеры являются иллюстрациями изящных целостных документов, которые вы можете создать с помощью среды MATLAB. Мы рассмотрим следующие примеры: • Освещение комнаты; • Залоговые платежи; • Моделирование Монте-Карло; • Математическая генетика; • Линейные экономические модели; • Линейное программирование; • Маятник 360°; • Ht Численное решение теплового уравнения; • $Г Модель транспортного потока. Мы не будем объяснять все команды среды MATLAB, которые будем использовать. Вы можете узнать о новых командах из оперативной справки. Программа Simulink используется в примере «Of Модель транспортного потока» и как вспомогательное средство в темах «Математическая генетика» и «1& Численное решение теплового уравнения». Пример «Линейное программирование» также потребует данные из наборов инструментов Optimization (Оптимизация) и программы Simulink. Примеры требуют различных уровней математической подготовки и опыта по другим предметам. Темы «Освещение комнаты», «Залоговые платежи» и «Математическая генетика» используют только математику из курса средней школы. Пример «Моделирование Монте-Карло» использует немного методов вероятности и статистики, «Линейные экономические модели» и «Линейное программирование» - немного линейной алгебры. Для задачи «Маятник 360°» окажутся полезными знания обыкновенных дифференциальных уравнений, для задачи «^ Численное решение теплового уравнения» - знания некоторых дифференциальных уравнений в частных производных и для задачи «^ Модель транспортного потока» - знания дифференциальных уравнений, линейной алгебры, а также хорошие отношения с функцией ez, где z - комплексное число. Даже если у вас нет подготовки для определенного примера, вы все-таки сможете узнать из него что-то новое о среде MATLAB.
лава 10. Прикладные задачи 175 Зсвешение комнаты Тредположим, что нам необходимо решить, в каком месте на потолке комнаты >азместить светильники, чтобы осветить комнату лучше всего. Размеры комнаты ледующие: длина равна 10 м, ширина составляет 4 м и высота - 3 м. По эстетиче- ким соображениям нас просят использовать небольшое число ламп накалива- шя. Мы хотим, чтобы общая мощность ламп накаливания не превышала 300 iarr. Как необходимо разместить данное количество ламп, чтобы добиться наи- юлыыей силы света в самой темной части комнаты? Мы также хотели бы знать, :аково будет улучшение при переходе от одной лампы накаливания мощностью 100 ватт к двум лампам по 150 ватт, к трем лампам по 100 ватт и так далее. Чтобы простить задачу, мы предполагаем, что в комнате нет никакой мебели и что :вет, отраженный от стен, незначителен по сравнению с прямым светом от ламп гакаливания. Эдна лампа на 300 ватт Пели есть только одна лампа накаливания, то мы поместим ее в центр потолка. Давайте нарисуем, насколько хорошо будет освещен пол. Мы вводим координату с, которая изменяется от 0 до 10 в длинном направлении комнаты, и координату Г, изменяющуюся от 0 до 1 в коротком направлении. Сила света в данной точке измеряется в ваттах на квадратный метр) - это мощность лампы накаливания, Ю0, разделенная на значение 4тт, умноженное на квадрат расстояния от лампы гакаливания. Так как лампа расположена на 3 м выше точки E; 2), расположений на полу, то мы можем выразить силу света в произвольной точке (х; у) на юлу следующим образом. >> syms х у; ilium = 300/D*pi*((х - 5)А2 + (у - 2)*2 + 3А2)) Lllum = 75/pi/((x - 5)А2 +(у - 2)Л2 + 9) Мы можем использовать функцию ezcontourf, чтобы построить график для этого выражения для всего пола. Мы воспользуемся параметром colormap для настроили цветового перехода, чтобы нам было легче видеть освещение. (Смотрите оперативную справку по дополнительным параметрам colormap.) >> ezcontourf (ilium, [0 10 0 4]) >> colormap ('gray1); axis equal tight
176 MATLAB 75/л/((х-5J+(у-2J+9) Самыми темными частями пола являются углы. Давайте найдем силу света в углах и в центре комнаты. >> subs (ilium, {x, у}, {0, 0}) ans = 0.6282 >> subs(illum/ {х, y}# {5# 2}) ans = 2.6226 Центр комнаты на уровне пола освещен приблизительно в четыре раза ярче, чем углы, когда на потолке установлена только одна лампа накаливания. Наша цель состоит в том, чтобы осветить комнату более однородно, используя больше ламп с той же самой общей мощностью. Перед тем, как перейти к нескольким лампам накаливания, мы заметим, что использование функции ezcontourf несколько ограничивает нас, поскольку эта функция не позволяет нам управлять числом контуров на наших изображениях. Это будет полезно для наблюдения за изменением силы света, поэтому мы выполним построения не в символьной форме, а численно. Для этого мы будем использовать функцию contourf вместо ezcontourf. Две лампы по 150 ватт В этом случае мы должны решить, где разместить эти две лампы накаливания. Здравый смысл велит нам расположить лампы накаливания симметрично в центре комнаты по линии вдоль длинных стен, другими словами, вдоль линии у = 2. Определим функцию, которая вычисляет силу света в точке (х; у) на полу от лампы накаливания 150 ватт, расположенной в точке (d; 2) на потолке. >> Iight2 = G(x, у, d) 150. / D*pi* ( (х - d).A2 + (у - 2).Л2 + 3*2)); Давайте представим картину освещения, если мы поместим один источник света в положение d = 3, а другой - в d = 7. Для этого и для последующих графиков мы установим 20 контуров на рисунке.
Глава 10. Прикладные задачи 177 >> [X, Y] = meshgrid @:0.1:10, 0:0.1:4); » contourf (light2(X# Y, 3) + light2(X# Y# 7), 20); >> colormap ('gray1); axis equal tight 40 60 80 100 Пол освещается более равномерно, чем с одной лампой накаливания, но светильники все еще расположены слишком близко друг к другу. Если мы переместим лампы накаливания еще дальше в стороны, то центр комнаты станет более тусклым, но углы станут более яркими. Давайте попробуем изменить положения светильников Had=2nd=8. >> contourf (light2(X, Y, 2) + light2(X, Y# 8), 20); >> colormap ('gray1); axis equal tight 40 60 80 100 Мы добились улучшения. Углы являются все еще самыми темными местами комнаты, несмотря на то, что сила света в середине комнаты (рядом с х = 5) продолжает уменьшаться по мере того, как мы увеличиваем расстояние между лампами. Однако, чтобы лучше освещать самые темные места, мы должны продолжить удалять лампы друг от друга. Давайте попробуем разместить источники света в положениях d = 1 nd = 9. >> contourf (light2(X# Y# 1) + light2(X# Y# 9), 20); >> colormap ('gray1); axis equal tight 4C 40 60 80 100
178 MATLAB Если взглянуть вдоль длинных стен, то комната теперь выглядит темнее в середине, чем в углах. Это указывает на то, что мы удалили лампы слишком далеко друг от друга. Мы могли бы продолжить строить другие графики контуров, но вместо этого давайте быть систематичными в поисках наилучшего положения для источников света. Вообще, мы можем поместить один источник света в точку х = d, а другой симметрично в х = 10 - d, где значение d находится в пределах от 0 до 5. Исходя из примеров, рассмотренных выше, самые темные места будут или в углах, или в середине двух длинных стен. По симметрии интенсивность будет одинакова во всех четырех углах, поэтому давайте изображать интенсивность в виде графика в одном из углов - точка @; 0) - как функцию от d. >> d = 0:0.1:5; » plot (d, light2@, 0, d) + light2@, 0, 10 - d)) 0.7 Можно предположить, что чем меньше будет значение d, тем более яркими окажутся углы. Напротив, график для интенсивности в средней точке E; 0) длинной стены (в силу симметрии не имеет значения, какую из двух длинных стен мы выберем) должен возрастать по мере того, как значение d приближается к 5. >> d = 0:0.1:5 ; plot(d, Iight2E, 0/ d) 2 Iight2E, 0# 10 - d)
Глава 10. Прикладные задачи 179 Мы изменяем величину параметра d, чтобы сделать наименьшее из этих двух значений на вышеупомянутых графиках (соответствующее самому темному месту в комнате) настолько высоким, насколько возможно. Мы сможем найти необходимое значение, если отобразим обе кривые на одном графике. » hold on; plot(d, light2@, 0, d) + light2@, 0, 10 - d))j » plot(d, Iight2E, 0, d) -b Iight2E, 0, 10 - d)); >> hold off Наилучшее значение d находится в точке пересечения, около точки A; 1), с наименьшей силой света немного ниже 1. Чтобы получить оптимальное значение d, нам необходимо точно найти точку, где пересекаются эти две кривые. >> syms d; » eqn = @(d) light2@, 0, d) + light2@, 0, 10 - d) - ... Iight2E, 0, d) - Iight2E# 0, 10 - d); >> dint = fzero(eqn, [0 5]) dint = 1.4410 Таким образом, лампы должны быть размещены приблизительно на расстоянии 1.44 м от коротких стен. Для такого расположения приблизительная сила света в самых темных местах на полу будет следующей. » light2@/ 0# dint) + light2@/ 0, 10 - dint) ans = 0.9301
180 MATLAB Сила света в самых темных местах в комнате равна приблизительно 0.93, в отличие от силы света 0.63 для случая с одной лампой накаливания. Таким образом, мы получили улучшение приблизительно на 50 %. Три лампы по 100 ватт Мы переопределим функцию силы света для ламп по 100 ватт. » Iight3 = @(х, у, d) 100. / D*pi* ((х - d).A2 + (у - 2).Л2 + 3*2)) light = @(х, у, d) 100./D*pi*((x - d)./42 + (у - 2).Л2 + 3Л2)) Предположим, что мы поместим одну лампу в центр комнаты и разместим две другие симметрично, как мы делали ранее. Здесь мы покажем освещение пола, когда боковые лампы накаливания удалены на 1 м от коротких стен. » [X#Y] =meshgrid @:0.1:10, 0:0.1:4); >> contourf (light3(X# Y, 1) + light3(X, Y, 5) + . . . Iight3 (X, Y# 9), 20); >> colormap('gray¦); axis equal tight 40 60 80 100 Кажется, что мы должны поместить лампы накаливания еще ближе к стенам. (Многим по эстетическим причинам такое размещение может не понравиться!) Пусть d обозначает расстояние от ламп накаливания до коротких стен. Мы определим функцию, вычисляющую силу света в положении х вдоль длинной стены и затем изобразим график силы света, как функцию от d для нескольких значений х. >> d = 0:0.1:5; >> for x = 0:0.5:5 plot(d, Iight3(x, 0# d) Iight3(x, 0, 10 - d)) hold on end; hold off Iight3(x, 0, 5)
Глава 10. Прикладные задачи 181 Нам известно, что для значений d, близких к 5, сила света увеличится по мере того, как значение х увеличивается от 0 до 5, таким образом, нижняя кривая соответствует х = 0, а верхняя кривая - х = 5. Обратите внимание на то, что кривая х = 0 расположена ниже других для всех значений d, а так же на то, что она повышается по мере уменьшения d. Таким образом, при d = 0 достигается наибольшая освещенность самых темных мест в комнате - ее углов (это соответствует х = 0). В этих местах сила света следующая. >> light3@, 0, 0) + light3@, 0, 5) + light3@, 0# 10) ans = 0.8920 Удивительно, но результат получался хуже, чем с двумя лампами накаливания. При переходе от двух ламп накаливания к трем и при уменьшении мощности каждой из ламп, нам необходимо уменьшить мощность на краях комнаты и сосредоточить ее в центре. Мы, возможно, смогли бы улучшить результат для случая с двумя лампами накаливания, если бы мы использовали более яркие лампы по краям комнаты и более тусклую лампу в центре или если мы использовали четыре лампы по 75 ватт. Но наши результаты пока указывают на то, что выигрыш, который может быть получен при переходе к больше, чем двум лампам, вероятно, будет меньше по сравнению с выигрышем, который мы получили при переходе от одной лампы к двум. Залоговые платежи Мы хотим найти зависимости между залоговым платежом с твердой процентной ставкой, суммой займа (заимствованными средствами), ежегодной процентной ставкой и сроком кредитования. Мы собираемся принять (как это обычно делается в Соединенных Штатах), что платежи производятся ежемесячно, даже в тех случаях, когда процентная ставка указывается за целый год. Давайте определим >> регуеаг = 1/12; percent = 1/100;
182 MATLAB Таким образом, число платежей по 30-летней ссуде будет » 30*12 ans = 360 и ежегодная процентная ставка, скажем, 8 % преобразуется в ежемесячную ставку > > 8 *percent *peryear ans = 0.0067 Теперь рассмотрим, что происходит с каждой ежемесячной оплатой. Часть оплаты приходится на то, чтобы выплачивать проценты по неоплаченной сумме займа, Р, а часть оплаты идет на уменьшение суммы займа должника. Общая сумма, R, ежемесячной оплаты остается постоянной в течение всего срока займа. Так, если J обозначает ежемесячную процентную ставку, то оплата для уменьшения суммы займа будет R - JP и новая сумма займа после внесения оплаты станет где m = 1 + J. Таким образом, таблица суммы займа все еще неоплаченной после п платежей для ссуды с начальной суммой А и для п от 0 до 6 сводится в таблицу следующим образом: >> syms m J P R A n >> disp('No. of Payments Remaining Principal1); >> P = A; >> for n a 0:6 disp([num2str(n), ¦', char(P)]) P - simplify(-R + P*m) ; end No. of Payments Remaining Principal 0 A 1 -R + A*m 2 -R-m*R + А*тЛ2 3 -R-m*R - mA2*R + А*тЛ3 4 -R-m*R - mA2*R - m/43*R + A*mA4
Глава 10. Прикладные задачи 183^ 5 -R-m*R - mA2*R - m/43*R - mA4*R + A*mA5 6 -R-m*R - mA2*R - mA3*R - mA4*R - mA5*R +A*mA6 Мы можем записать это более простым способом, обратив внимание на то, что P=Amn+ (термины для вычисления оплаты R) Например, при п = 7 мы получим: » factor(Р - А*тА7) ans = -R* A+т+тА2+тА3+тА4+тА5+тА6) Но с другой стороны, выражение в круглых скобках является суммой геометрического ряда Л-1 -^Л 1 Таким образом, мы видим, что сумма займа после п платежей может быть записана как P = Amn-R(mn-l)/(m-l) Теперь мы можем найти ежемесячную сумму оплаты R, исходя из предположения, что ссуда будет выплачена за N взносов, то есть Р уменьшиться до 0 за N платежей: >> syxns N; » solve (A*mAN - R* (mAN - l)/(m - 1), R) R = subs(ans/ m, J + 1) ans = A*mAN*(m-l)/(mAN-l) R = A*(J + l)AN*J/((J+l)AN-1) Например, если первоначальная сумма займа А = 150000 $и срок займа составляет 30 лет C60 платежей), то мы получаем следующую таблицу сумм оплат, как функцию ежегодной процентной ставки: >> format bank; » dispC Rate D) Monthly Payment ($)');
184 MATLAB >> for rate = l:10# disp([rate, double(subs(R, {A, N, J}, ... {150000, 360# rate*percent*peryear>))]) end Rate (%) Monthly Payment ($) 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00 482.06 553.51 630.83 713.74 801.89 894.85 992.17 1093.36 1197.95 1305.48 Обратите внимание на использование команды format bank, чтобы выводить числа с плавающей запятой с двумя цифрами после десятичной точки. Есть другой способ понять эти вычисления, он несколько хитроумнее и использует возможности среды MATLAB из области линейной алгебры. А именно, мы можем записать основное уравнение в матричной форме это выражение выглядит следующим образом где и Мы можем проверить полученное выражение с помощью перемножения матриц:
Глава 10. Прикладные задачи 185 >> syms R Р; В = [m -R; 0 1] ; v = [Р; 1] ; B*v ans = m*P-R 1 что соответствует формуле, которую мы рассматривали выше. Таким образом, вектор-столбец [Р; 1], получающийся после п платежей, может быть вычислен с помощью умножения слева начального вектора [А; 1] на матрицу Вп. Полагая, что m > 1, то есть, задана положительная процентная ставка, вычисления >> [eigenvectors, diagonalform] = eig(B) eigenvectors = [ 1, 1] [ 0, (m-l)/R] diagonalform = [ m, 0] [ 0, 1] показывают нам, что матрица В обладает собственными значениями хп, 1 и собственными векторами (О) ((m-l)/R) [j/RJ Теперь мы можем записать вектор [А; 1] как линейную комбинацию собственных векторов: Мы можем найти коэффициенты: >> [х, у] = solve('A = х*1 + у*1', '1 = х*0 + y*J/R") х = (A*J-R) /J У = 1/J*R
186 MATLAE таким образом, мы получим И Таким образом, сумма займа, остающаяся после п платежей, равна: Мы получили такой же результат, что и ранее. Чтобы подвести итог, давайте определим сумму денег А, которую заемщик может позволить себе заимствовать как функцию от того, какую ежемесячную плату R он может позволить себе выплачивать. Мы просто решаем наше уравнение относительно А, предполагая, что будет Р я 0 после N платежей. » solve(A*mAN - R*(mAN - l)/(m - 1), А) ans = R* (mAN-l) / (mAN) / (m-1) Например, если вы покупаете дом и можете позволить себе платить 1500 $ в месяц за 30-летний займ с постоянной процентной ставкой, то наибольшая сумма займа как функция от процентной ставки будет » dispC Rate (Ч) Maximal Loan ($)'); » for rate ¦ 1:10, disp([rate, double(subs(ans, {R, N, m}, ••• {1500, 360, 1 + rate*percent*peryear}))]) end Rate (%) 1.00 2.00 3.00 4.00 5.00 6.00 Maximal Loan (?) 466360.60 405822.77 355784.07 314191.86 279422.43 250187.42
Глава 10. Прикладные задачи 187 7. 8. 9. 10 00 00 00 .00 225461.35 204425.24 186422.80 170926.23 Моделирование Монте-Карло Чтобы выполнить долгосрочное статистическое прогнозирование результатов, для вероятностного процесса часто полезно провести моделирование, основанное на понимании основных вероятностей. Эта операция называется метод Монте-Карло. В качестве примера мы рассмотрим игру в казино, когда игрок держит пари против казино, а казино выигрывает в 51 % случаев. Вопрос заключается в следующем: сколько игр должно пройти прежде, чем с достаточной уверенностью можно будет сказать, что казино скорее склонно к выигрышам, чем к проигрышам? Этот сценарий достаточно обычен, так что математики давно установили весьма точную статистику по этому вопросу. Но здесь мы хотим показать, как получить хорошее представление о том, что может случиться на практике, не погружаясь глубоко в математику. Сначала мы получим выражение, которое на основании случайного числа вычисляет чистый доход казино от одной игры. Для создания случайного числа от 0 до 1 мы воспользуемся функцией rand из среды MATLAB. Если случайное число получилось меньше или равно 0.51, то казино выигрывает одно пари, если число превышает 0.51, то казино проигрывает пари. (В игре с высокими ставками каждая ставка может стоить 1000 $. Таким образом, казино важно знать, как много проигрышей ему придется выдержать прежде, чем получить прибыль, чтобы сразу же не обанкротиться!) Следующее выражение выдает 1, если результат функции rand будет меньше, чем 0.51, и -1, если результат функции rand будет больше, чем 0.51 (мы так же получим 0, если результат функции rand будет точно равен числу 0.51, но такой случай крайне маловероятен). >> revenue = sign@.51 - rand) revenue = -1 Чтобы смоделировать сразу несколько игр, скажем, десять игр, мы можем с помощью команды rand A, 10) создать вектор из десяти случайных чисел и затем применить эту же операцию. >> revenues = sign@.51 - rand(l, 10)) revenues =
188 MATLAB Columns 1 through 5 1.00 -1.00 1.00 -1.00 -1.00 Columns 6 through 10 1.00 1.00 -1.00 1.00 -1.00 Каждое число 1 представляет игру, в которой казино выиграло, а каждое значение -1 представляет игру, в которой оно проиграло. Для большего числа игр, скажем 100, в среде MATLAB мы можем просуммировать доход от отдельных пари следующим образом: >> profit = sum (sign @.51 - randd, 100))) profit = -4 Результат представляет чистую прибыль (или убытки, если он отрицательный) для казино после 100 игр. В среднем за каждые 100 игр казино должно выигрывать 51 раз, а игрок (и), должны выигрывать 49 раз, таким образом, казино должно получить прибыль в 2 единицы (в среднем). Давайте посмотрим, что получится в нескольких пробных запусках. >> profits = sum(sign@.51 - randA00, 10))) profits = Columns 1 through 5 14.00 -12.00 6.00 2.00 -4.00 Columns 6 through 10 0 -10.00 12.00 0 12.00 Мы видим, что чистая прибыль может значительно колебаться от одного набора 100 игр к другому и что существует большая вероятность того, что казино потеряет деньги после 100 игр. Чтобы получить представление о том, как чистая прибыль может быть распределена в общем случае, мы можем повторить наш эксперимент большое число раз и построить гистограмму результатов. Следующая функция вычисляет чистую прибыль для к различных испытаний по п игр каждое. >> profits = @(n# k) sum(sign@.51 - rand(n, к))) profits = @(n,k) sum(sign@.51 - rand(n, k))) Эта функция должна создать матрицу из случайных чисел размером n x k и затем выполнить те же самые операции, что были проделаны выше с каждым элементом матрицы, чтобы получить матрицу с записями 1, если казино выиграло, и -1 - для игр, когда казино проиграло. Наконец, данная функция суммирует столбцы
Глава 10. Прикладные задачи 189 матрицы, чтобы получить вектор-строку из к элементов, каждый из которых представляет общую прибыль от столбца за п игр. Теперь мы построим гистограмму результатов функции profits для п = ЮОик = 100. Теоретически, казино могло выиграть или потерять до 100 единиц, но практически мы находим, что результаты почти всегда находятся в пределах 30 или около 0. Таким образом, необходимо построить столбцы гистограммы в промежутке от -40 до 40 с приращениями 2 (поскольку чистая прибыль всегда одинакова после 100 игр). » hist (profits A00, 100), -40:2:40); axis tight -40 -20 0 20 40 Гистограмма подтверждает наше предположение о том, что присутствует широкое изменение результатов после 100 игр. Похоже, что потерять деньги для казино столь же вероятно, что и получить прибыль. Однако распределение, показанное выше, достаточно беспорядочно, и это подсказывает нам, что мы должны провести большее число испытаний, чтобы увидеть лучшее приближение к действительному распределению. Давайте попробуем выполнить 1000 испытаний. » hist (profits A00, 1000), -40:2:40); axis tight
190 MATLAE Согласно теореме центрального предела, когда и п, и к являются большими чис лами, гистограмма должна быть сформирована в виде «колоколообразной кривой», и на рисунке выше мы видим, что эта форма начинает появляться. Давайте перейдем дальше к 10000 испытаниям. » hist (profits A00, 10000), -40:2:40); axis tight Здесь мы очень ясно видим форму колоколообразной кривой. Хотя мы не установили, насколько вероятно, что казино будет в проигрыше после 100 игр и насколько большой в этом случае может быть его чистый убыток, мы приобрели уверенность, что наши результаты хорошо описывают распределение возможных результатов после 1000 испытаний. Теперь мы рассмотрим чистую прибыль после 1000 игр. Мы ожидаем, что казино в среднем выиграет 510 игр, а игроку (ам) повезет в 490 играх, то есть чистая прибыль получиться 20 единиц. Давайте начнем с 1000 испытаний. » hist (profits A000, 1000), -100:10:150); axis tight Поскольку диапазон значений, которые мы наблюдаем для прибыли после 1000 игр шире, чем диапазон для 100 игр (диапазон возможных значений в десять раз больше), то результаты получились ближе друг к другу, чем ранее. Это отражает теоретический принцип (также следствие теоремы центрального предела), что средний «разброс» результатов после большого числа испытаний должен быть пропорционален квадратному корню из числа хх игр, проводившихся в каждом
Глава 10. Прикладные задачи 191 испытании. Это важно для казино, поскольку если бы разброс был бы пропорционален п, то казино никогда не могло быть достаточно уверено в получении прибыли. Когда мы увеличиваем п в 10 раз, разброс может увеличиться только в л/10 раз или немного больше, чем в 3 раза. Обратите внимание на то, что после 1000 игр казино более вероятно будет в выигрыше, чем в убытках. Однако вероятности неудач для казино все еще выглядят значительными. Давайте повторим моделирование с 10000 испытаниями, чтобы убедиться в наших результатах. Мы могли бы поддаться соблазну и ввести hist (profits A000, 10000), -100:10:150), но обратите внимание, что это выражение использует массив из 10 миллионов чисел. Хотя большинство компьютеров теперь могут хранить такие большие массивы в памяти, использование таких больших объемов памяти может привести к замедлению работы среды MATLAB. Вообще, мы считаем, что лучше не заходить слишком далеко за миллион элементов в массиве, когда это возможно. На наших компьютерах в этом случае быстрее выполнить эти 10000 испытаний в партиях по 1000 игр, используя цикл, чтобы собрать результаты в один вектор. >> profitvec = []; >> for j = 1:10 profitvec = [profitvec profitsA000, 1000)]; end » hist(profitvec, -100:10:150); axis tight 1200 Мы видим, что форма колоколообразной кривой появляется снова. Хотя это и маловероятно, но возможность того, что казино будет проигрывать 50 единиц после 1000 игр, весьма велика. Если каждая единица стоит 1000 $, то мы могли бы посоветовать казино приготовить, по крайней мере, 100 000 $ наличных денег, чтобы быть готовым к такому исходу событий. Возможно даже, что этой суммы будет недостаточно. Чтобы определиться с этим вопросом, мы должны продолжить наши опыты.
192 MATLAB Теперь давайте посмотрим, что происходит после 10000 игр. Мы ожидаем, что в этой случае казино в среднем будет выигрывать 200 единиц и на основе нашего раннего рассмотрения диапазон значений, который мы используем для построения гистограммы, необходимо увеличить примерно в три раза по сравнению с предыдущим случаем. Давайте перейдем непосредственно к 10000 испытаниям. На сей раз мы сделаем 100 партий по 100 испытаний в каждой из них. >> profitvec = [] ; >> for j = 1:100 profitvec = [profitvec profitsA0000, 100)]; end » hist(profitvec, -200:25:600); axis tight 1000 800 600 400 200 -°200 i J 0 1 m 200 чии 601 Кажется, что получение прибыли после 10000 игр для казино весьма вероятно. Но хотя шанс на потерю весьма мал в данном случае, он не незначителен. Больше, чем 1% испытаний привел к убыткам, и иногда убытки составляли больше, чем 100 единиц. Однако общая тенденция к доходности кажется ясной, и мы ожидаем, что после 100000 игр казино, вероятно, в подавляющем большинстве испытаний получит прибыль. На основе предыдущих наблюдений роста разброса результатов мы ожидаем, что в большинстве случаев чистая прибыль будет в пределах 1000 при ее ожидаемом значении равном 2000. Каждое из 10000 испытаний по 10000 игр требует определенного времени на выполнение, поэтому сейчас мы сделаем только 1000 испытаний. >> profitvec = [ ]; » for j = 1:100 profitvec = [profitvec profitsA00000, 10)]; end » hist (profitvec, 500:100:3500); axis tight
Глава 10. Прикладные задачи 193 1000 1500 2000 2500 3000 3500 Результаты соответствуют нашим предположениям. Казино определенно получит прибыль после 100000 игр, но оно должно держать под рукой запас из нескольких сотен единиц игр, чтобы покрыть возможные потери во время работы. Математическая генетика Мы хотим посмотреть на две модели прироста численности вида. Первая модель представляет собой обыкновенную экспоненциальную модель роста/спада, ко- горая весьма хорошо описывает вымирание вида или кратковременное изменение его численности при беспрепятственном росте. Вторая, более правдоподобная, модель описывает рост вида в условиях ограниченного пространства, недостатка пищи и активности конкурентов или хищников. Экспоненциальный рост/спад vlbi предполагаем, что начальная численность вида равна Ро. Измененную чис- юнность через п единиц времени мы обозначим Рп. Предположим, что в каждом феменном интервале численность увеличивается или уменьшается на постоян- гую часть от ее значения в начале интервала. Таким образом, Pn+i=P«+rPn, п>0. 1остоянная г отражает различие между коэффициентом рождаемости и показа- елем смертности. Численность увеличивается, если г является положительной ;еличиной, уменьшается, если постоянная г отрицательна, и остается постоян- юй в случае, если г = 0. {алее мы предлагаем простой М-файл для вычисления численности в стадии п, читывая при этом численность в предыдущей стадии и коэффициент г. > type itseq unction X = itseq(f, Xinit, n, r) Вычисляет повторяющуюся последовательность значений •1605
194 MATLAI X = zeros(n + 1, 1) ; X(l) = Xinit; for к = l:n X(k + 1) = f (X(k) , r); end Фактически, это простая программа для итерационных вычислений значени! последовательности хк+1 = f (хк# г), п > 0, для заданной функции f, значени: ее параметра г и начального значения х0 этой последовательности. Теперь давайте применим эту программу, чтобы вычислить численность дву: видов за 5-летние промежутки времени для г = 0.1, а затем г = -0.1: » Xinit = 100; f = @(х# г) х*A + г); » X = itseq (f# Xinit# 100# 0.1); >> format long; X(l:5:101) ans = 1.0e+006 * 0.00010000000000 0.00016105100000 0.00025937424601 0.00041772481694 0.00067274999493 0.00108347059434 0.00174494022689 0.00281024368481 0.00452592555682 0.00728904836851 0.01173908528797 0.01890591424713 0.03044816395414 0.04903707252979 0.07897469567994 0.12718953713951
Глава 10. Прикладные задачи 195 0.20484002145855 0.32989690295921 0.53130226118483 0.85566760466078 1.37806123398224 » X = itseq (?, Xinit, 100, -0.1); X(l:5:101) ans = 1.0е+002 * 1.00000000000000 0.59049000000000 0.34867844010000 0.20589113209465 0.12157665459057 0.07178979876919 0.04239115827522 0.02503155504993 0.01478088294143 0.00872796356809 0.00515377520732 0.00304325272217 0.00179701029991 0.00106111661200 0.00062657874822 0.00036998848504 0.00021847450053 0.00012900700782 0.00007617734805 0.00004498196225 0.00002656139889
196 MATLAE В первом случае численность растет быстро, а во втором - быстро уменьшается Действительно, из модели видно, что для любого п отношение Pn/Pn+i = A + г) и из этого следует, что Рп = Ро A + r)n, n > 0. Это выражение используется для расчета экспоненциального роста/спада. Эта модель предсказывает рост численности без какого-либо ограничения (для видов с увеличивающейся чис ленностью) и поэтому она не является правдоподобной. Наша следующая модель учитывает сдерживание роста численности, вызванное ограниченным простран ством, ограниченными пищевыми ресурсами, конкурентами и хищниками. Логистический рост Предыдущая модель предполагает, что относительное изменение численности постоянно, то есть Теперь давайте добавим условие, которое будет сдерживать рост, а именно Мы упростим задачу, приняв, что и = 1 + г так, что наша рекурсивная связь примет вид где и является положительной постоянной. В этой модели численность Р должна лежать между 0 и 1, и она должна быть понята как процент от максимально возможной численности в рассматриваемой окружающей среде. Так что давайте определим функцию, которую мы будем использовать в процедуре итерации: » f = G(x, u) u*x*(l - x); Теперь давайте вычислим несколько примеров и воспользуемся командой plot, чтобы отобразить результаты. » Xinit = 0.5; X = itseq(f, Xinit, 20, 0.5); plot(X) » X 5 10 15 20 itseq(?, Xinit, 20, 1); plot(X) 25
Глава 10. Прикладные задачи 197  5 10 15 20 25 >> X = itseq(f, Xinit, 20, 1.5); plot(X) 0.45 0.4 0.35 j i 1 i - i i i \ > > X 0 5 10 15 20 itseq(?, Xinit, 20, 3.4); plot(X) 0.9 0.8 0.7 0.6 0.5 0.4 Ii| I ! i I ! I II ii Л !i (I i! ii i M 111 ПИ I I l| |l |!i| ii I I j I Ii ii l| i! i ! I ij | ii !' i! | ii i I ( f ? 10 15 20 25 25 Ь первом вычислении мы использовали нашу итерационную программу, чтобы 1ычислить плотность популяции для 20 временных промежутков, принимая ло- истическую постоянную роста и = 0.5 и начальную плотность популяции 50 %. 1ид, по всей вероятности, вымирает. В остальных примерах мы сохранили на- [альную плотность популяции в 50 %, единственное, что мы изменили - это ло- истическую постоянную роста. Во втором примере с постоянной роста и = 1 ;ид вымирает снова, хотя и более медленно. В третьем примере с постоянной
198 MATLAE роста 1.5 численность вида, похоже, стабилизируется около значения 33.3... % Наконец, в последнем примере с постоянной 3.1 численность вида, кажется, ко леблется между плотностями приблизительно 45 % и 84 %. Эти примеры показывают замечательные возможности логистической модели ма тематической генетики. Эта модель совершенствовалась на протяжении более 150 лет Возникновение модели основано на работах бельгийского математика Верхалста Здесь мы приведем некоторые из фактов, связанные с этой моделью. Мы подтвер дим некоторые из них с помощью среды MATLAB. В частности, помимо команды plot мы будем использовать команду bar, чтобы отобразить некоторые из данных. • Логистическая постоянная не может быть больше, чем 1. Чтобы модель работала верно, результат в любой точке должен быть между 0 и 1 Но парабола ихA - х) на промежутке 0 <х <1 достигает наибольшей высоть при х в 1/2, где ее значение равно и/4. Чтобы сохранить значение в проме жутке между 0 и 1, мы должны ограничить и ? 4. А вот что произойдет, если \; окажется больше 4: >> X = itseq(?, 0.5, 10, 4.5) X = l.Oe +173 * 0.00000000000000 0.00000000000000 -0.00000000000000 -0.00000000000000 -0.00000000000000 -0.00000000000000 0.00000000000000 0.00000000000000 -0.00000000000000 0.00000000000000 -8.31506542713596 • Если 0 ? и ? 1, то плотность популяции стремится к нулю при любом началь ном значении. » X - itseq(?, 0.5, 100, 0.8); ХA01) ans = 2.420473970178059е-11 X = itseq(f, 0.5, 20, 1); bar(X)
Глава 10. Прикладные задачи 199 10 15 20 25 • Если 1 < и ? 3, то численность вида стабилизируется на плотности 1 - 1/и при любой начальной плотности, отличной от нуля. Третий из исходных четырех примеров подтверждает это утверждение (cue 1.5 и 1 - 1/и ¦ 1/3). В следующих примерах мы установим и ¦ 2, 2.5 и 3, так, чтобы выражение 1 - 1/и равнялось 0.5, 0.6 и 0.606.... Сходимость в последнем вычислении медленная (как можно было бы ожидать от граничного случая или «точки раздвоения»). » X о itseq(?, 0.25, 100, 2); ХA01) ans = 0.50000000000000 » X = itseq (?, 0.75, 100, 2); ХA01) ans = 0.50000000000000 >> X в itseq (?, 0.5, 20, 2.5);
200 » X = itseq (f, 0.5, 100# 3); » bar (X); axis ([0 100 0 0.8]) MATLAE • ЕслиЗ < u < 3.56994 20 40 60 80 100 . ., то присутствует повторяющийся цикл. Эта теория является весьма тонкой. Для получения более полного объяснения читатель может обратиться к книге «Encounters with Chaos» (Столкновения с хаосом), Дэнни Галик, McGraw-Hill, Нью-Йорк, 1992, Раздел 1.5. Фактически существует последовательность uQ =3<w, =l+v6 <щ <м3...<4, такая, что между и0 и Ui существует цикл с периодом 2, между м1 и и2 - цикл с периодом 4, то есть между uk и uk+1 существует цикл с периодом 2k+1. В действительности известно, что, по крайней мере, для небольших значений к существует приближение Uk+l = 1 + у]3 + ик . Таким образом, >> ul = 1 + sqrtF) ul = 3 .44948974278318 >> u2approx = 1 + sqrt C + ul) u2approx = 3.53958456106175 Это объясняет колебательное поведение, которое мы видели в последних примерах (cu0 < u = 3.4 < Ui). Ниже показано поведение для Ui < u = 3.5 < и2. » X ш itseq(f# 0.75, 100, 3.5); » bar(X); axis([0 100 0 0.9])
"лава 10. Прикладные задачи 201 > Значениеu < 4, за которым-хаос! У1ожно доказать, что последовательность uk стремиться к пределу и». Значение i«, иногда называемое «параметр Фигенбаума», равно приблизительно 3.56994.... Давайте посмотрим, что получится, если мы выберем значение и из промежутка >т параметра Фигенбаума до 4. >> X = itseq (f, 0.75, 100, 3,7); >> plot (X); axis ([0 100 0 1]) 0.8 0.6 0.4 0.2 ¦ i | '1 ''I V { 1 20 40 60 80 100 Это пример того, что математики называют «хаотическим» явлением! Оно не :лучайно - последовательность была создана точно, с помощью определенных математических операций, но результаты не показывают какого-либо различимого образца. Хаотические явления непредсказуемы, но с помощью современных методик (включая компьютерный анализ) математики стали в состоянии нахо- щтъ определенные образцы поведения в беспорядочных явлениях. Например, юследний рисунок наводит на мысль о возможности непостоянных периодиче- :ких циклов и других повторяющихся явлений. Действительно, ученым известно много информации. Вышеупомянутая книга Галика будет прекрасным материа- юм, также, как и источником превосходной библиографии по этой теме.
202 MATLAB Повторный запуск модели с помошью программы Simulink Логистическая модель роста, которую мы исследовали, очень хорошо подходит для моделирования с помощью .программы Simulink. Ниже показана простая модель для программы Simulink, которая соответствует рассмотренным выше выражениям: >> open_system popdyn Индикатор Генератор импульса Давайте кратко рассмотрим, как эта модель работает. Если мы не будем учитывать блок Pulse Generator (Генератор импульса) и блок Sum (Сумма) в левой нижней части рисунка, то эта модель будет действовать согласно уравнению х в следующий момент = ихA - х) в текущий момент, которое является уравнением для логистической модели. Блок Scope (Индикатор) отображает график х как функцию от (дискретного) времени. Однако мы должны каким-то образом ввести начальное условие для х. Здесь мы покажем самый простой способ сделать это: мы добавим к правой стороне дискретный импульс, который является начальным значением х (здесь мы используем 0.5) во время t = 0, и он равен 0 во все последующие моменты времени. Так как модель дискретна, вы можете достигнуть этого, установив блок Pulse Generator (Генератор импульса) в режим Sample based (Основанный на образце), выбрав для периода импульса большее значение, чем длительность моделирования, приняв ширину импульса равной 1 и установив амплитуду импульса равной начальному значению х. Результаты, полученные с помощью этой модели, для двух интересных случаев и « 3 • 4 и и = 3.7 показаны здесь: » [t, х] = aim(•popdyn', [0 120]); » sixnplot(t, x); title('u = 3.4')
Глава 10. Прикладные задачи 203 В первом случае, при и = 3.4, отчетливо видно периодическое поведение. >> setjaramt'popdyn/Logistic Constant^ «Value1, '3.71) [t, x] = sim('popdyn', [0 120]); » simplot(t, x); title(*u = 3.7») С другой стороны, когда и = 3.7, мы получаем беспорядочное поведение. Линейные экономические модели Возможности линейной алгебры среды MATLAB предоставляют хорошие средства для изучения линейных экономических моделей, иногда называемых «модели Леонтьева» (в честь их первого разработчика, лауреата Нобелевской премии экономиста Василия Леонтьева). Мы приведем несколько примеров. Самой простой такой экономической моделью является «модель линейного обмена» или «замкнутая модель Леонтьева». Эта модель предполагает, что экономика делится, скажем, на п секторов, таких как сельское хозяйство, производство, обслуживание, потребление и т.д. Каждый сектор получает продукцию от различных секторов (включая себя) и производит результат, который распределяется среди различных секторов. (Например, сельское хозяйство производит пищу для домашнего потребления и для экспорта, но также и зерно, и новый домашний скот,
204 MATLAB которые повторно инвестируются в сельскохозяйственный сектор, так же обстоит дело и с химическими веществами, которые могут использоваться производственным сектором, и так далее.) Значение замкнутой модели состоит в том, что полное производство равняется полному потреблению. Экономика находится в равновесии, когда каждый сектор экономики становится (по крайней мере) безубыточным. Для этого необходимо, чтобы цены на различные продукты регулировались бы рыночными механизмами. Пусть ai/D- обозначает часть продукции j-ro сектора, которая потребляется i-м сектором. Тогда элементы а±^ являются элементами квадратной матрицы, называемой «матрица обмена» А, у которой сумма элементов любого из столбцов равна 1. Пусть р± будет ценой продукции i-ro сектора экономики. Поскольку каждый сектор должен стать безубыточным, Pi не может быть меньше значения затрат, потребляемых i-м сектором, или другими словами, Но при суммировании по i с учетом, что мы увидим, что эти две стороны выражения должны быть равными. На матричном языке это означает, что (I - А)р = 0, где р является вектором-столбцом цен. Таким образом, р является собственным вектором матрицы А для собственного значения 1. Теория вероятностных матриц подразумевает (допуская, что А является «несократимой», то есть, что нет никакого подходящего подмножества Е секторов экономики, такого, что все продукты из Е оставались бы внутри этого подмножества), что р уникально определяется с точностью до скалярного коэффициента. Другими словами, замкнутая несократимая линейная экономика обладает уникальным состоянием равновесия. Например, если у нас есть » А = [0.3, 0.1# 0.05# 0,2; 0.1, 0.2, 0.3, 0.3; ... 0.3, 0.5, 0.2, 0.3; 0.3, 0.2, 0.45, 0.2] А = 0.3000 0.1000 0.3000 0.3000 тогда >> sum (A) 0.1000 0.2000 0.5000 0.2000 0.0500 0.3000 0.2000 0.4500 0.2000 0.3000 0.3000 0.2000
Глава 10. Прикладные задачи 205 1111 го есть, суммы всех столбцов равны 1, и » [V# D] = eig(A); D(l# 1) » Р = V(: , 1) ans = 1.0000 Р = 0.2739 0.4768 0.6133 0.5669 зидно, что 1 является собственным значением для матрицы А с собственным век- гором цен р. Несколько более точной является (неподвижная, линейная) открытая экономическая модель Леонтьева, которая учитывает рабочую силу, потребление и т.д. Давайте рассмотрим эту модель на примере. В следующих вычислениях мы будем использовать действительную таблицу деловых операций для экономики Великобритании за 1963 год. (Мы взяли эту таблицу из книги «Input-Output Analysis ind its Applications» (Анализ затрат и результатов и его применение), Р. Э'Коннор и Е. В. Генри, Hafner Press, Нью-Йорк, 1975.) Подобные таблицы можно получить из официальной государственной статистики. Таблица Т представляет собой матрицу размером 10 х 9. В качестве единиц измерения в ней вы- эраны миллионы британских фунтов. Ряды представляют соответственно сель- :кое хозяйство, промышленность, услуги, межотраслевой итог, импорт, продажи конечным покупателям, косвенные налоги, заработную плату и прибыль, общие первичные затраты и общие затраты. Столбцы представляют соответственно :ельское хозяйство, промышленность, услуги, межотраслевой итог, потребление, привлечение капитала, экспорт, общий конечный спрос и производство. Гаким образом, результаты от каждого сектора могут быть прочитаны по ряду, а затраты на сектор могут быть прочитаны по столбцу. » Т = [277 444 14 735 1123 35 51 1209 1944; ... 587 11148 1884 13619 8174 4497 3934 16605 30224; ... 236 2915 1572 4723 11657 430 1452 13539 18262;
206 MATLAB -90 2675 0 4355 -177 100 0 173 88 17 0 378 -179 2792 0 4906 0; 3487; 26826; 36259; 1100 14507 3470 19077 20954 4962 5437 31353 50430; 133 2844 676 3653 1770 250 273 2293 5946; 3 134 42 179 -246 499 442 695 954 12240 13632 26826 844 15717 14792 31353 1944 30224 18262 50430 25309 5135 5815 36259 86689]; Некоторые из свойств этой матрицы видны из следующих операций: » ТD, :) - ТA, :) - ТB, :) - ТC, :) Т(9, :) - ТE, :) - ТF, :) - ТG, :) - Т(8, :) ТA0, :) - ТD, :) - Т(9# :) ТA0# 1:4) - ТA:4, 9)' ans 0 ans 0 ans 0 ans 0 — 00 = 00 00 = 00 Таким образом, четвертый ряд, который суммирует межотраслевые затраты, является суммой первых трех рядов, девятый ряд, который суммирует «первичные затраты», является суммой рядов с 5 по 8. Десятый ряд, показывающий полные затраты, является суммой рядов 4 и 9, а первые четыре элемента последнего ряда соответствуют первым четырем элементам последнего столбца (подразумевая, что вся продукция из промышленных секторов учтена). Также мы получим: , 4) - Т(:, 1) - T(i, 2) - Т(:, 3))' 8) - Т(:# 5) - Т(:, 6) - Т(:, 7))' (Т(:# 9) - Т(:, 4) - Т(:, 8))'
Глава 10. Прикладные задачи 207 ans = 00 00000000 ans = 0 000000000 ans = 00 00000000 гаким образом, четвертый столбец, представляя общую межотраслевую продукцию, равен сумме столбцов с 1 по 3; восьмой столбец, представляя общий «конечный спрос», равен сумме столбцов с 5 по 7, и девятый столбец, представляя всю продукцию, является суммой столбцов 4 и 8. Матрица А «межотраслевых технических коэффициентов» получается при делении столбцов матрицы Т промышленных секторов (в нашем случае есть три из них) на соответствующие общие затраты. Таким образом, мы получаем: » А = [Т(:, 1)/ТA0, 1), Т(:, 2)/ТA0, 2)# Т(:# 3)/ТA0, 3)] А = 0.1425 0.0147 0.0008 0.3020 0.3688 0.1032 0.1214 0.0964 0.0861 0.5658 0.4800 0.1900 0.0684 0.0941 0.0370 0.0015 0.0044 0.0023 -0.1265 0.0165 0.0242 0.4907 0.4050 0.7465 0.4342 0.5200 0.8100 1.0000 1.0000 1.0000 Здесь элементы в верхнем квадрате (первые три ряда) являются самыми важными, поэтому мы выполним замену >> А = АA:3, :) А = 0.1425 0.0147 0.0008
208 MATLAB 0.3020 0.3688 0.1032 0.1214 0.0964 0.0861 Если вектор Y представляет общий конечный спрос для различных промышленных секторов, а вектор X представляет всю продукцию для этих секторов, то последний столбец матрицы Т равен сумме столбцов 4 (общая межотраслевая продукция) и 8 (общий конечный спрос) и мы получаем матричное уравнение = (\-A)X. Давайте проверим это уравнение: » Y = ТA:3, 8); X = ТA:3# 9); Y - (еуе(З) - А)*Х ans = 0 0 0 Теперь можно выполнять различные числовые эксперименты. Например, как изменится количество продукции при увеличении конечного спроса на промышленную продукцию на 10 миллиардов фунтов A0.000 в единицах нашей задачи) без увеличения спроса на услуги или на сельскохозяйственную продукцию? Так как экономика, как мы предполагаем, является линейной, изменение ЛХ для X получается при решении линейного уравнения AY=(l-A)AX, и >> deltaX = (еуе(З) - А) \ [0; 10000; 0] deltax = 1.0е+04 * 0.0280 1.6265 0.1754 Таким образом, сельскохозяйственная продукция увеличилась бы на 280 миллионов фунтов, объем промышленного производства увеличился бы на 16.265 миллиардов фунтов, а производительность сферы обслуживания увеличилась бы на 1.754 миллиарда фунтов. Мы можем показать результат от подобных увеличений спроса для других секторов с помощью следующих круговых диаграммам: » deltaXl = (еуе(З) - А) \ [10000; 0; 0];
Глава 10. Прикладные задачи 209 >> deltaX2 = (еуе(З) - А) \ [0; 0; 10000]; >> subplotA, 3, 1), pie(deltaXl, {'Ag.1, 'Ind.1, 'Serv.'}) » subplotd, 3# 2), pie(deltaX, {'Ад.1, "Ind.1, "Serv.'}) >> title(['Effect of increases in demand for each of the ¦ ... •3 sectors1]/ 'FontSize1, 13) » subplotd, 3, 3)# pie(deltaX2# {'Ag.1, 'Ind.4 'Serv.1}) >> colormap(gray) Effect of increases in demand for each of the 3 sectors Serv. Agserv. 4 i Линейное программирование Среда MATLAB идеально подходит для решения так называемых задач линейного программирования. В таких задачах у вас есть величина, линейно зависящая от нескольких переменных, которые вы хотите увеличить или уменьшить и которые подчинены нескольким ограничениям. Эти ограничения выражаются как линейные неравенства в тех же самых переменных. Если количество переменных и число ограничений невелики, то существует множество математических методов для решения задач линейного программирования. Действительно, такие методы часто преподаются в средней школе или курсах университетской математики. Но иногда эти числа довольно велики или, даже если они малы, константы в линейных неравенствах или выражение для параметра объекта, который предстоит оптимизировать, могут оказаться весьма сложными для численного решения. В этом случае, чтобы найти решение, необходимо использовать такие пакеты программ, как среда MATLAB. Мы покажем метод линейного программирования на простом примере, давая сочетание графического и численного решений, а затем решим как немного более сложную задачу, так и весьма непростой пример. Предположим, что у фермера есть 75 акров, чтобы посадить две зерновые культуры: пшеницу и ячмень. Выращивание этих зерновых культур будет стоить фермеру (за семена, удобрения и т.д.) 120 $ за акр для пшеницы и 210 $ за акр для ячменя. У фермера есть в наличии 15 000 $ на расходы. Но после сбора урожая он должен хранить зерновые культуры, ожидая благоприятного состояния рынка. Фермер владеет складскими площадями вместимостью 4000 бушелей. Каждый акр позволяет вырастить в среднем 110 бушелей пшеницы или 30 бушелей ячменя. Если чистая прибыль за бушель пшеницы (после того, как все расходы вычтены)
210 MATLAB равна 1.30 $, а для ячменя - 2.00 $, то как должен фермер засеивать 75 акров, чтобы достичь наибольшей прибыли? Мы начнем с математической формулировки задачи. Сначала мы выразим цель (целью в нашей задаче является прибыль) и ограничения алгебраически, затем мы построим график, и, наконец, мы найдем решение с помощью графического исследования и небольшого арифметического расчета. Пусть х обозначает число акров, выделенных для пшеницы, а у - число акров, выделенных для ячменя. Тогда можно записать следующее выражение, для которого необходимо подобрать наибольшее значение, чтобы получить наибольшую прибыль Р = A10)A.30)х + C0)B.00)у = 143х + бОу. Есть три ограничивающих неравенства, заданные пределами на расходы, на хранение и на площади земли для посевов. Они, соответственно, следующие: 120х + 210у < 15000, 110х + ЗОу ^ 4000, х + у < 75. Строго говоря, есть еще два ограничивающих неравенства, вызванные тем, что фермер не может засеять отрицательное число акров, а именно, 0, 0. Затем мы строим графики для областей, определенных этими ограничениями. Последние два ограничения говорят, что мы должны рассмотреть только первый сектор в плоскости х - у. Ниже показан график, очерчивающий треугольную область в первом секторе, определенную первым неравенством. >> X = 0:125; » Y1 = A5000 - 120.*Х)./210; » area(X# iuu 120
Глава 10. Прикладные задачи 211 Теперь давайте добавим два других ограничивающих неравенства. » Y2 о хпах(D000 - 11О.*Х)./ЗО, 0); » Y3 ¦ хоахG5 - X, 0); » Ytop = min([Yl; Y2; Y3]); >> area(X, Ytop) 80- 701 601 501 401 301 ~0 20 40 60 80 100 120 Довольно трудно ясно видеть многоугольную границу области. Давайте немного увеличим рисунок. » area(X, Ytop); axis([0 40 40 75]) 75 701 651 601 551 501 451 40( Теперь давайте наложим на вершину этого изображения график целевой функции Р. >> hold on » [U V] ш meshgrid @:40, 40:75); » contour (U, V, 143.*U + 60.*V); hold off
212 MATLAB 75 70 65 60 55 50 45 40 V \ \ \ \ \ \ \ \ \ i \ i \ i\ \ ¦ \ \ х \ \ \ - , V 10 40 Кажется очевидным, что максимальное значение Р появится на кривой уровня (являющейся линией уровня), которая проходит через вершину многоугольника, расположенного рядом с точкой B2; 53). Фактически мы можем вычислить >> [х# у] = solveCx + у = 75'# '110*х + 30*у = 4000 •) х = У = 175/8 425/8 double([х, у] ) ans = 21.8750 53.1250 Площадь земли, которая приводит к наибольшей прибыли, равна 21.875 для пшеницы и 53.125 для ячменя. В этом случае прибыль составит » Р = 143*х + бО*у Р = 50525/8 >> format bank; double(P) ans = 6315,62 то есть, 6 315.62$.
Глава 10. Прикладные задачи 213 Эта задача показывает пример «фундаментальной теоремы линейного программирования», которая используется здесь для двух переменных: линейное выражение ах+by, определенное на замкнутом ограниченном выпуклом множестве S, стороны которого являются линейными сегментами, достигает своих наибольших и наименьших значений в вершинах S. Если множество S неограничено, то в нем может быть, но не должно быть оптимальное значение, но если оно там есть, то оно находится в одной из вершин. (Выпуклое множество - это множество, для которого любой линейный сегмент, присоединяющийся к двум точкам множества, полностью находится в этом множестве.) Ц Фактически, набор инструментов программы Simulink содержит встроенную функцию simlp, которая выполняет решение задач линейного программирования. Набор инструментов Optimization (Оптимизации) содержит почти такую же функцию, которая называется linprog. Вы можете узнать о любой из них из оперативной справки. Мы будем использовать в нашей задаче функцию simlp. Позже мы будем применять эту функцию для решения двух других, более сложных задач, затрагивающих больше переменных и ограничений. Ниже показано начало текста справки для этой функции. >> helptext = help('simlp1); helptextA:190) ans = SIMLP Helper function for GETXO; solves linear programming problem. Xi=SIMLP(f, A, b) solves the linear programming problem: min f 'xsubject to: Ax <= b x Итак, » f = [-143 -60]; » A = [120 210; 110 30; 1 1; -1 0; 0 -1]; » b = [15000; 4000; 75; 0; 0]; >> format short; simlp(f, A, b) ans = 21.8750 53.1250 Мы получили тот же самый ответ, что и ранее. Обратите внимание на то, что мы получили отрицательные коэффициенты для целевой функции Р в векторе ?, потому что функция simlp ищет минимум, а не максимум. Заметьте также, что ограничения неотрицательности приняты во внимание в последних двух рядах А и Ь.
214 MATLAB Хорошо, мы, возможно, могли бы решить эту задачу вручную. Но предположите, что фермер занимается выращиванием третьей зерновой культуры, скажем, кукурузы, и что данные выглядят следующим образом. • Стоимость за акр: 150.75 $. • Урожай на акр: 125 бушелей. • Прибыль на бушель: 1.56 $. Если мы обозначим число акров, выделенных под кукурузу через z, то целевая функция примет вид Р=A10)A.30)х+C0)B.00)у+A25)A.56)=143x+60y+195Z/ и ограничивающие неравенства будут 120х + 210у + 150.75Z ? 15000, 110х + ЗОу + 125z ? 4000, х + у + z <> 75, х^0, у^0, z? 0. С помощью функции simlp задача решается следующим образом: » f ш [-143 -60 -195]; >> А = [120 210 150.75; 110 30 125; 1 1 1; -10 0; ... 0 -1 0; 0 0 -1]; » Ъ = [15000; 4000; 75; 0; 0; 0] ; » simlp(f, А, Ь) ans = 0 56.5789 18.4211 Таким образом, фермер должен отказаться от пшеницы и засеять 56.5789 акров ячменя и 18.4211 акров кукурузы. Нет практически никакого предела в количестве переменных и ограничений, с которыми среда MATLAB может обращаться. Конечно, в разумных пределах - нет никакого ограничения для задач, с которым относительно простой пользователь может столкнуться.
Глава 10. Прикладные задачи 215 Действительно, во многих настоящих прикладных задачах техники линейного программирования приходится учитывать многие переменные и ограничения. Решение таких задач вручную невозможно и использование такого программного обеспечения, как среда MATLAB является решающим фактором для успеха. Например, в задаче из сельского хозяйства, которую мы рассмотрели, можно было учитывать больше зерновых культур, чем две или три - подразумевая сельское хозяйство вместо семейного фермерства. Также можно было принять во внимание ограничения, которые вызваны влиянием других обстоятельств помимо расходов, хранения и ограничений площади земли - например, следующие. • Доступность семян. Этот фактор мог бы привести к ограничивающему неравенству вида Xj ? к. • Личное предпочтение. Например, супруга фермера могла бы отдать предпочтение одному варианту вместо другого и настаивать на посеве выбранной культуры или нескольких зерновых культур. Таким образом, могут появиться такие ограничивающие неравенства, как хА ? х^илихх + х2 ^ х3. • Государственные дотации. Они могут привести к таким неравенствам, как х-, ? к. Ниже представлена последовательность команд, которая решает эту задачу. Вы должны суметь увидеть выражение для целевой функции и ограничения, наложенные на данные. Но в качестве подсказки вы можете использовать следующие вопросы. • Сколько зерновых культур рассматривается? • Каковы расходы? Сколько средств можно потратить на расходы? • Каковы урожаи в каждом случае? Какова вместимость хранилища? • Сколько акров земли доступно? • На какие зерновые культуры оказывают влияние ограничения количества семян? В какой степени? • Что можно сказать о предпочтениях? • Каковы наименьшие площади земли для каждой зерновой культуры? » f = [-110*1.3 -30*2.0 -125*1.56 -75*1.8 -95*.95 ... -100*2.25 -50*1.35]; >> А = [120 210 150.75 115 186 140 85; ... 110 30 125 75 95 100 50; 1 1 1 1 1 1 1; 1 0 0 0 0 0 0; ... 001000 0; 0000010; 1-10000 0; ... 0 0 1 0 -2 0 0; 0 0 0 -1 0 -1 1; -1 0 0 0 0 0 0; ... 0-10000 0; 00-1000 0; 000-100 0; ...
216 MATLAB 0000-10 0; 00000-10; 000000-1]; » b = [55000; 40000; 400; 100; 50; 250; 0; 0; 0; -10; -10; ... -10; -10; -20; -20; -20]; >> simlp (?, A, b) ans = 10.0000 10.0000 40.0000 45.6522 20.0000 250.0000 20.0000 Обратите внимание на то, что, несмотря на сложность задачи, среда MATLAB решает задачу практически мгновенно. Похоже, что фермеру необходимо делать ставку на сельскохозяйственную культуру под номером 6. Мы предлагаем вам изменить в этой задаче расходы и/или предел хранения и посмотреть, как это повлияет на результат. Маятник 360° Обычно мы представляем маятник как некоторый вес, подвешенный с помощью гибкой нити или каната таким образом, что он может качаться вперед и назад. Другой вид маятника состоит из веса, закрепленного на легком (но твердом) прутке к оси так, чтобы он мог поворачиваться на большие углы и при достаточной заданной скорости даже выполнять вращения на 360°. Уравнения движения Хотя в действительности это не совсем верно, но мы все же часто предполагаем, что величина сил трения, которые, в конечном счете, приводят к остановке маятника, пропорциональна скорости маятника. Предположим также, что длина маятника равна 1 м, масса на конце маятника составляет 1 кг, а коэффициент трения примем 0.5. В таком случае, уравнения движения для маятника будут следующими. = -0.5y(t)-9.8\sm(x(t)),
Глава 10. Прикладные задачи 217 где t представляет время в секундах, х обозначает угол отклонения маятника от вертикальной линии в радианах (то есть х = 0 - это исходное положение), у выражает угловую скорость маятника в радианах в секунду, а постоянная 9.81 - это приблизительное ускорение, вызванное действием силы тяжести, в метрах в секунду в квадрате. Ниже показан ход решения для начального положения х@) = 0 и начальной скоростью у @) = 5. Это график х и у как функции от t на промежутке времени 0 < t <20. (Чтобы использовать инструмент среды MATLAB для численного решения дифференциальных уравнений ode45, мы объединим х и у в один вектор х - смотрите оперативную справку для команды ode45.) » g = @(t, x) [xB); -0.5*xB) - 9.81*sin(x(l))]; » [t, xa] = ode45(g, [0:0.01:20], [0 5]); >> plot(xa(:, 1), xa(:# 2)) 6г Вспомните, что координата х соответствует углу маятника, а координата у соответствует его скорости. Начав в точке @; 5), по мере увеличения t, мы следуем за кривой, в то время как она закручивается по часовой стрелке к точке @; 0). Маятник колеблется назад и вперед, но с каждым колебанием угол отклонения становится меньше, пока маятник совсем не вернется в состояние покоя ко времени t = 20. Одновременно скорость также периодически изменяется, достигая своих наибольших значений в течение каждого колебания, когда маятник находится в середине своего колебания (угол близок к нулю), и достигает нуля, когда маятник находится в конце своего колебания. Увеличение начальной скорости Мы увеличим начальную скорость до 10 . » [t, xa] = ode45(g, [0:0.01:20], [0 10]); » plot(xa(:,l)# xa(:,2))
218 MATLAB На этот раз угол увеличивается до значения, превышающего 14 радиан, перед тем, как кривая подходит к точке примерно A2.5; 0). Если быть более точными, кривая закручивается к точке Dп; 0), потому что 4п радиан представляет то же самое положение маятника, что и 0 радиан. Маятник выполнил два полных оборота перед началом своих затухающих колебаний. Скорость сначала уменьшается, но затем повышается после того, как угол проходит через п, поскольку маятник проходит вертикальное положение и получает импульс. Импульса маятника будет достаточно только чтобы еще раз пройти через вертикальное положение в угле Зп. Нахождение начальной скорости, которая заставляет маятник совершать полные вращения Предположим, что мы хотим с точностью до 0.1 найти наименьшее значение начальной скорости, которая требуется, чтобы заставить маятник, начинающий движение из своего исходного положения, выполнить полное вращение один раз. Будет полезно показать решения, которые соответствуют нескольким различным начальным скоростям на одном графике. Сначала мы рассмотрим целые значения скорости в промежутке от 5 до 10. >> hold on >> for а в 5:10 [t, xa] a ode45(g, [0:0.01:20], [0 а]); plot(xa(:, 1)# xa(:, 2)) end >> hold off
Глава 10. Прикладные задачи 219 Начальные скорости 5, 6 и 7 не являются достаточно большими, чтобы увеличить угол более п, но начальные скорости 8, 9 и 10 достаточны, чтобы заставить маятник сильно качаться. Давайте посмотрим, что происходит на промежутке между 7 и 8. Второй шаг >> hold on >> for а в 7.0:0.2:8.0 [t, ха] о ode45(g, [0:0.01:20], [0 а]); plot(xa(:, I), xa(:, 2)) end >> hold off -5 0 5 10 15 Мы видим, что ответ находится где-то между 7.2 и 7.4. Давайте выполним еще одно уточнение. Третий шаг >> hold on >> for а в 7,2:0.05:7.4 [t, ха] = ode45(g, [0:0.01:20], [0 а]); plot(xa(:, 1), ха(:, 2)) end » hold off
220 MATLAB Мы пришли к выводу, что наименьшая необходимая скорость находится где-то между 7.25 и 7.3. Численное решение теплового уравнения В этом разделе мы будем использовать среду MATLAB для численного решения теплового уравнения (известного также как уравнение диффузии), а также для решения дифференциального уравнения в частных производных, которое описывает много физических явлений, например, проводящий тепловой поток или диффузию примесей в неподвижной жидкости. Вы можете представить протекание диффузии как каплю краски, распространяющуюся в стакане воды. (До некоторой степени вы могли бы также изобразить сливки в чашке кофе, но в этом случае перемешивание, которое появляется при заливке сливок в кофе, усложняет задачу в силу появления движения жидкости, которое впоследствии может ускориться, если мы станем размешивать кофе.) Краска состоит из большого числа отдельных частиц, каждая из которых неоднократно отскакивает от окружающих водных молекул, следуя в действительности по случайному пути. Так как частиц краски очень много, то их индивидуальные случайные движения образуют чрезвычайно детерминированную общую модель, поскольку краска распространяется равномерно во всех направлениях (здесь мы не учитываем возможный результат от действия силы тяжести). Подобным образом вы можете представить тепловую энергию, распространяющуюся благодаря случайным взаимодействиям соседних частиц. В трехмерной среде тепловое уравнение выглядит следующим образом Здесь и является функцией от t, х, у и z. Эта функция представляет температуру, или концентрацию примесей в случае диффузии, во время t и для положения в среде (х# у, z). Постоянная к зависит от используемых материалов и называется удельной теплопроводностью в случае рассмотрения теплового потока или
Глава 10. Прикладные задачи 221 коэффициентом диффузии для задачи, связанной с явлениями диффузии. Чтобы упростить задачу, давайте предположим, что среда не трехмерна, а одномерна. В этом случае можно рассмотреть диффузию в тонкой заполненной водой трубе или тепловой поток в тонком изолированном проводе. Давайте, прежде всего, рассмотрим случай теплового потока. Тогда дифференциальное уравнение в частных производных примет вид ди д2и ? а?' где u (х# t) - температура во время t на расстоянии х вдоль провода. Решение методом конечных разностей Чтобы решить это дифференциальное уравнение в частных производных, нам необходимы оба начальных условия в форме и (х, 0) = f (х),где? (х) дает температурное распределение в проводе во время 0 и граничные условия в конечных точках провода, назовем их х = а и х = Ь. Мы выбрали так называемые граничные условия Дирихле u (a, t) =Таии (b# t) = Tb, которые соответствуют температурам, равным постоянным значениям Та и Ть в этих двух конечных точках. Хотя в данном случае можно получить и точное решение, позвольте нам показать численный метод конечных разностей. Для начала отметим, что мы можем хранить на компьютере последовательность значений температуры и только в дискретном наборе времен и для дискретного набора положений х. Пусть времена будут 0, At, 2At ... NAt, и пусть положения будут а, а + Ах ... а + JAx = b, aunD- = u (a + jAt# nAt). После переписывания дифференциального уравнения в частных производных в соответствии с условиями конечно-разностной аппроксимации для производных, мы получим к At Ах2 Это самые простые аппроксимации, которые мы можем использовать для производных, и этот метод может быть повторно выполнен с использованием более точных приближений, особенно для производной t. Таким образом, если для отдельного п мы знаем значения un3- для всех j, то мы можем решить уравнение, показанное выше, для каждого j, где s = kAt/(АхJ. Другими словами, это уравнение говорит нам, как найти температурное распределение в шаге времени п + 1, зная температурное распределение в шаге времени п. (В конечных точках j = 0 и j = J, это уравнение обращается к температурам, находящимся вне ограниченного диапазона для х, но в этих точках мы не будем учитывать данное уравнение, а вместо этого применим
222 MATLAB граничные условия.) Мы можем воспринимать это уравнение, считая, что температура в данном положении в следующем шаге является средневзвешенным числом его температуры и температур соседних участков в текущем шаге времени. Другими словами, во время At данный участок провода длины Ах передает каждому из своих соседних участков часть своей тепловой энергии s и сохраняет остающуюся часть 1 - 2s. Таким образом, наше численное воплощение теплового уравнения является дискретной версией микроскопического описания диффузии, которую мы привели вначале, когда тепловая энергия распространяется благодаря случайным взаимодействиям между соседними частицами. Следующий М-файл, который мы назвали heat.m, вычисляет описанные выше операции. >> type heat function u = heat(k, t, x, init, bdry) % Решает одномерное тепловое уравнение на прямоугольнике, % заданным векторами х и t с начальным условием u(t(l),x)= init % и граничными условиями Дирихле u (t, х A)) = bdry A), % и (t, х (end)) = bdry B). J = length(x); N = length (t); dx = mean (diff(x)); dt = mean (diff(t)); s = k*dt/dx/42; и = zeros (N, J); и A, : ) = init ; for n = 1:N-1 u(n+l,2:J-l) = s*(u(n,3:J) +u(n,l:J-2)) + ... (l-2*s)*u (n, 2: J-l); и (n+1,1) = bdry(l); и (n +1,J) = bdryB) ; end Функция принимает в качестве входных параметров значение к, значения векторов t и х, вектор начальных значений init (предполагается, что его длина равна длине вектора х), а также вектор bdry, содержащий пару краевых значений. В результате выполнения этой функции получается матрица значений и. Обратите внимание на то, что индексы массивов в среде MATLAB должны начинаться с 1, а не с 0. Мы немного отклонились от нашего более раннего примечания, что п ¦ 1
Глава 10. Прикладные задачи 223 соответствует начальному времени, a j = 1 соответствует левой конечной точке. Обратите внимание также на то, что в первой строке после оператора цикла for мы вычисляем весь ряд и за исключением первых и последних значений, в одной строке; каждый элемент является вектором длиной J - 2, с индексом j, увеличенным на 1 в элементах и (п, 3: J) и уменьшенным на 1 в элементах и (п# 1: J-2). Давайте используем М-файл, показанный выше, чтобы решить одномерное тепловое уравнение с к = 2 на промежутке -5 < х < 5 для диапазона времен от 0 до 4, используя граничные температуры 15 и 25 и начальное температурное распределение 15 для х < 0 и 25 для х > 0. Вы можете представить, что во время 0 два отдельных провода с различными температурами и длиной 5 соединяются в положении х = 0, и каждый из их дальних концов остается в окружающей среде, которая поддерживает значения температур неизменными. Мы должны выбрать значения для At и Ах, давайте попробуем использовать At = 0.1 и Ах = 0.5 так, чтобы получилось 41 значение t на промежутке от 0 до 1 и 21 значение х в интервале от -5 до 5. >> tvals = linspace@, 4, 41); >> xvals = linspace(-5, 5, 21); >> init я 20 + 5*sign(xvals); >> uvals = heatB7 tvals, xvals, init, [15 25]); >> surf(xvals, tvals, uvals) >> xlabel x; ylabel t; zlabel u Здесь мы использовали команду surf, чтобы показать общее решение u (x, t). Очевидно, что полученный результат неправдоподобен. Обратите внимание на масштаб по оси и! Численное решение дифференциальных уравнений в частных производных чревато опасностями, а неустойчивость, как было отмечено выше, является распространенным недостатком алгоритмов метода конечных разностей. Для многих дифференциальных уравнений в частных производных алгоритм метода конечных разностей не будет работать вообще, но для теплового уравнения и других подобных уравнений этот метод будет хорошо работать при правильном выборе At и Ах. Можно было предположить, что поскольку мы выбрали
224 MATLAB достаточно большое Лх, то выбранное значение следовало бы уменьшить, но на самом деле это только ухудшило бы положение. В конечном счете, единственным параметром в итерации, который мы используем, является постоянная s, а единственным недостатком выполнения всех вычислений в М-файле, как мы делали выше, является то, что мы не можем видеть промежуточные значения, которые получаются в ходе вычисления. В этом случае мы можем легко подсчитать, что s = 2@.1)/@.5J = 0.8. Обратите внимание, что это подразумевает, что коэффициент 1 - 2 s для unD- в итерации выше отрицателен. Таким образом, «среднее взвешенное», которое мы описали прежде, в нашем понимании итерационного шага не является истинным средним значением; каждый участок провода передает больше энергии, чем он обладает - в каждом шаге времени! Решение задачи, описанной выше, состоит в том, чтобы правильно уменьшить шаг времени At. Например, если мы сократим шаг в два раза, тогда станет s = 0.4, а все коэффициенты в итерации будут положительными. >> tvals = linspace@, 4, 81); >> uvals = heatB# tvals, xvals, init, [15 25]); >> surf(xvals, tvals, uvals) >> xlabel x; ylabel t; zlabel u Получилось значительно лучше! По мере увеличения времени распределение температуры, похоже, приближается к линейной функции х. Действительно, и (х, t) = 20 + х является ограничением «устойчивого состояния» для этой задачи. Оно удовлетворяет граничным условиям и выдает 0 с обеих сторон дифференциального уравнения в частных производных. Вообще говоря, хорошо обладать хотя бы начальными знаниями теории дифференциальных уравнений в частных производных перед тем, как пытаться решать их численными методами, как мы делали выше. Однако, по крайней мере, для этого отдельного случая простое эмпирическое правило сохранения коэффициентов в итерации положительными приводит к верным результатам. Теоретическое исследование устойчивости алгоритма для метода конечных разностей при решении одномерного теплового уравнения показывает, что, действительно,
Глава 10. Прикладные задачи 225 подойдет любое значение s между 0 и 0.5, и предлагает, что лучшее значение At, которое следует использовать для данного Ах - это значение, которое делает s = 0.25. Обратите внимание, что в то время как мы можем получить более точные результаты при уменьшении Ах, если мы уменьшим его в 10 раз, то для компенсации мы должны уменьшить At в 100 раз. В этом случае вычисления потребуют в 1000 раз больше времени и в 1000 раз больше памяти! Случай переменной проводимости Ранее мы упоминали, что задача, которую мы решили численно, могла также быть решена аналитически. Ценность численного метода заключается в том, что его можно применить к подобным дифференциальным уравнениям в частных производных, для которых точное решение найти невозможно или, по крайней мере, оно не известно. В качестве примера мы рассмотрим одномерное тепловое уравнение с переменным коэффициентом, которое представляет неоднородный материал с переменной удельной теплопроводностью к (х). ди д (., ч ди Л . / ч д2и 19/ .ди — = — к(х)— \ = к(х)—т + к(х)—. dt дх{ } дх) дх2 дх Для первых производных с правой стороны мы используем симметрическую конечно-разностную аппроксимацию так, чтобы наше дискретное приближение к дифференциальным уравнениям в частных производных станет . к J At j Ах2 2Ах 2Дх ' к (а + j Ах). Тогда шаг времени для этого метода будет u"+x = Sj(Uj+l +и\_х ) + (l-2sj )и" +0.25(sj+x -Sj_x )(wj+1 ~и"-\ )> где Sj = kjAt/(AxJ. В следующем М-файле, который мы назвали heatvc.m, мы изменим наш предыдущий М-файл, чтобы включить эту итерацию. >> type heatvc function u = heatvc(k, t, x, init, bdry) % Решает одномерное тепловое уравнение с переменным % коэффициентом к на прямоугольнике, описанном векторами х и t % с u(t(l), x) = init и граничными условиями Дирихле % u(t, хA)) = bdry(l), u(t, x(end)) = bdryB). J = length(x); N = length (t); 3-1605
226 MATLAB dx = mean(diff(x)); dt = mean(diff(t) ) ; s = k*dt/dxA2; u = zeros (N, J); u( 1 , : ) = init; for n = 1:N-1 u(n + 1,2:J-1) = sB:J-l).*(u(n,3:J) + u(n/l:J-2)) + ... A - 2 * s B: J-l)).*u (nf 2: J - 1) + ... 0.25*(sC: J) - s(l:J-2)).*(u (n, 3:J) - u(n, 1:J - 2)); u (n + 1, 1) = bdry(l) ; u (n + 1,J) = bdry B) ; end Обратите внимание, что теперь к, как предполагалось, является вектором той же самой длины, что и х, а также, и вектора результата s. Это в свою очередь требует, чтобы мы использовали векторное умножение в основной итерации, которую мы теперь разделили на три строки. Давайте воспользуемся этим М-файлом, чтобы решить одномерное тепловое уравнение с переменным коэффициентом для тех же самых граничных и начальных условий, что и ранее, используя к(х) = 1 + (х/5J. Так как наибольшее значение к равно 2, то мы можем использовать те же самые значения At и Ах. » kvals = 1 + (xvals/5).A2; >> uvals = heatvc(kvals, tvals, xvals, init, [15 25]); >> surf(xvals, tvals, uvals) >> xlabel x; ylabel t; zlabel u
Глава 10. Прикладные задачи 227 В этом случае предельное температурное распределение нелинейно. Оно имеет более крутой температурный градиент в середине, где удельная теплопроводность ниже. Напомним, что можно найти точную форму этого предельного распределения, u (х, t) =20 A + A/п) arc tan (x/5)), приравняв производную t к нулю в исходном уравнении и решив получившееся обыкновенное дифференциальное уравнение. Вы также можете использовать метод конечных разностей, чтобы решить тепловое уравнение в двух или трех координатах. Для этого и других дифференциальных уравнений в частных производных, в которые входят время и две плоскости координат, вы можете также использовать набор инструментов PDE (ДУЧП), который предоставляет более совершенный «метод конечных элементов». Решение с помощью программы Simulink Мы можем также решить тепловое уравнение, используя программу Simulink. Чтобы сделать это, мы продолжим приближать производные х с помощью конечных приращений, но будем представлять уравнение как векторнозначное обыкновенное дифференциальное уравнение, где t выступает как независимая переменная. Программа Simulink решает модель, используя средство решения ОДУ среды MATLAB, - ode45. Чтобы показать, как это можно сделать, давайте рассмотрим пример, с которого мы начали. В этом случае к = 2 на промежутке -5 < х й 5 от времени 0 до времени 4, используются граничные температуры 15 и 25, а начальное распределение температуры 15 - для х < 0 и 25 для х > 0. Мы заменяем функцию u(x, t) для постоянного t вектором и, содержащим значения u(x, t), например, для х = -5:5. Здесь получается 11 значений х, для которых мы отберем и, но так как функция u(x, t) предопределена в конечных точках, мы можем сделать и девятимерным вектором, и в конце мы только присоединим значения в конечных точках. Так как мы заменяем отношение d2/dx2 его конечно-разностной аппроксимацией и для простоты мы взяли их = 1, то наше уравнение становится векторнозначным ОДУ — dt Здесь правая сторона представляет наше приближение к к{ д и I дх ). Матрица А выглядит следующим образом -2 1 ... 0 1 -2 ¦•. ; ... 1 • ¦ ¦ 1 О ... 1 -2
228 MATLAB так как мы заменяем д и I дх в (n, t) наи(п - 1, t) - 2u(n, t) + u(n + 1, t). Мы представляем эту матрицу в обозначениях среды MATLAB как 2*eye (9) + diag((81), 1) + diag((8, 1), -1). Вектор с получается из граничных условий, и его первый элемент равен 15, а последний элемент равен 25, элементы между ними - 0. Мы представим это в обозначениях среды MATLAB как [15; zeros G,1); 25]. Формула для с получается, исходя из того, что иA) представляет u(-4# t) u д U / дх в этой точке приближается к u(-5, t) - 2u(-4# t) + u(-3, t) = 15 - 2u(l) + uB) также и в другой конечной точке. Ниже показана модель программы Simulink, представляющая это уравнение: >> open_system heateq.mdl 1 s Интегратор ь Приращение А г I ^ к -С- Условия Индикатор ' ' Обратите внимание, что необходимо определить начальные условия для и как свойства блока Integrator (Интегратор), и что в диалоге Block Parameters (Свойства блока) для блока Gain (Приращение) требуется установить вид умножения Matrix (Матричное). Значения с и A) пои D) представляют решение и (х, t) вх = -4 до-1, а значения с и(б) до и (9) представляют решения и (х, t) вх = 1 до 4, мы принимаем начальное значение и равным [15*ones D,1); 20; 25*ones D,1)]. (Мы используем число 20 как компромисс в х = 0, так как это значение справедливо в середине областей, где и равно 15 и 25.) Результат выполнения модели отображается в блоке Scope (Индикатор) в виде графиков различных элементов и как функции от t, но более полезно сохранить результат в рабочем пространстве среды MATLAB и затем построить его с помощью команды surf. Кстати, это помогает переустанавливать пределы оси Y на блоке Scope (Индикатор), чтобы переходить от 15 к 25. Чтобы внести эти изменения и запустить модель от t = 0 к t = 4, мы выполним следующие команды >> set_param(•heateq/Scope¦, ¦YMin•, '15'); >> set_param( 'heateq/Scope', 'YMax1, '25'); » [tout, uout] = simCheateq.mdl1, [0,4]); >> simplot(tout, uout)
Глава 10. Прикладные задачи 229 Таким образом, мы сохраним результат моделирования (для времени от 0 до 4) как вектор tout, а вычисленные значения и как uout, как матрицу с девятью столбцами. Каждый ряд этих массивов соответствует одному шагу времени, а каждый столбец uout соответствует одному значению х. Но помните, что мы должны добавить к значениям вектора и дополнительные столбцы значений в конечных точках. Таким образом, мы строим график для данных следующим образом: >> и = [15*ones(length(tout), 1), uout, ..• 25*ones(length(tout),l)]; >> х = -5:5; >> elf reset >> set(gcf, 'Color1, 'White1) >> sur?(x, tout, u) >> xlabeM'x1), ylabelff), zlabeK'u1) >> title("Solution to heat equation in a rod1) Уравнение проводимости
230 MATLAB Обратите внимание, насколько этот график похож на изображение, полученное нами ранее для постоянной проводимости к = 2. Мы оставляем читателю возможность поэкспериментировать с моделью для случая переменной проводимости. Решение с помощью команды pdepe Среда MATLAB содержит встроенную команду pdepe для решения дифференциальных уравнений в частных производных в одной координатной плоскости (содержащие и время t). Чтобы узнать больше об этой функции, прочитайте оперативную справку, посвященную pdepe. Инструкции по использованию pdepe весьма подробны, но требуют математической подготовки. Метод, который использует данная команда, в какой-то степени похож на метод, использованный нами ранее в решении с помощью программы Simulink. To есть команда использует средство решения ОДУ в t и в конечных приращениях х. Следующий М-файл решает вторую задачу, рассмотренную выше, с переменной проводимостью. Обратите внимание на использование описания функции и подфункций. >> type heateqex2 function heateqex2 % Решает задачу Дирихле для теплового уравнения в стержне, % теперь с переменной проводимостью, 21 узел сетки. m = 0; Это просто говорит, что геометрия линейна. х = linspace(-5,5,21); t = linspace@,4,81) ; sol = pdepe(m,@pdex,@pdexic,@pdexbc,x,t); % Выделяет первый элемент решения как и. и = sold, :,1); % Объемное отображение часто помогает найти решение. surf(х,t,u) title('Numerical solution computed with 21 mesh points in x.1) xlabel('x'), ylabel (¦ t ¦) f zlabeK'u1) function [c,f,s] = pdex(x,t,u,DuDx) с = 1; f = A + (x/5).A2)*DuDx; s = 0; a __ function uO = pdexic(x) % % начальное условие при t = 0 uO = 20+5*sign(x); Q» function [pl,ql,pr,qr] = pdexbc(xl,ul,xr,ur,t) % значения q равны нулю из-за условий Дирихле % pi = 0 - в левой конечной точке, рг = 0 - в правой точке pi = ul-15;
Глава 10. Прикладные задачи 231 qi = 0; pr = ur-25; qr = 0; После выполнения мы получим: >> heateqex2 Численное решение, вычисленное с 21 узлом сетки вх 25 О -5 t х Результаты опять очень похожи на то, что мы получили ранее. Модель транспортного потока Наверное, каждому из нас приходилось просиживать в пробке или наблюдать скопление автомобилей на дороге без какой-либо видимой серьезной причины. Среда MATLAB и программа Simulink являются хорошими инструментами для изучения модели такого поведения. Наш анализ будет основан на так называемых теориях «следования за лидером» для транспортного потока. Об этих теориях вы можете прочесть больше в книге «Kinetic Theory of Vehicular Traffic» (Кинетическая теория автомобильного движения), Ильва Пригожий и Роберт Герман, Elsevier, Нью- Йорк, 1971 или в книге «The Theory of Road Traffic Flow» (Теории потока дорожного транспорта), Уинифред Аштон, Methuen, Лондон, 1966. Мы проанализируем здесь чрезвычайно простую модель, которая уже показывает непростое поведение. Мы рассмотрим одностороннюю круговую дорогу с одной полосой движения и с множеством автомобилей на ней (очень простая модель, скажем, для внешней петли кольцевой дороги вокруг Вашингтона, округ Колумбия; поскольку в очень плотном движении нелегко изменить полосу движения, то каждая полоса ведет себя как отдельная дорога с одной полосой). Каждый водитель замедляет движение или разгоняется исходя из своей текущей скорости, скорости автомобиля впереди и расстоянием до этого автомобиля. Но люди за рулем обладают конечным временем реакции. Другими словами, им требуется определенное время (обычно около одной секунды), чтобы понять, что происходит вокруг них, и нажать педаль газа или затормозить. Стандартная теория «следования за лидером» предполагает, что
232 MATLAB (*) где t - это время, Т - время реакции, и„ - это положение n-ого автомобиля, а «коэффициент чувствительности» X может зависеть от Un_i(t) - Un(t) (от промежутка между автомобилями) и/или от un(t) (от скорости n-го автомобиля). Смысл этого уравнения заключается в следующем. Водитель будет склонен к замедлению движения, если его автомобиль движется быстрее, чем автомобиль перед ним, или если его автомобиль находится близко к автомобилю впереди, и, наоборот, будет стремиться к увеличению скорости, если его автомобиль движется медленнее, чем автомобиль перед ним. Кроме того, водитель (особенно при неинтенсивном движении) может быть склонен к ускорению или замедлению, в зависимости от того, движется ли его автомобиль медленнее или быстрее, чем «разумная» скорость для данной дороги (часто, но не всегда, эта скорость равна указанной предельной скорости). Так как наша дорога является круговой, то в этом уравнении и0 воспринимается как uN, где N является общим количеством автомобилей. Самой простой версией модели является версия, в которой «коэффициент чувствительности» X является (положительной) постоянной величиной. Тогда мы получим однородное линейное дифференциальное/разностное уравнение с постоянными коэффициентами для скоростей un (t). Очевидно, что есть «установившееся» решение, когда все скорости равны и постоянны (то есть, движение протекает на постоянной скорости), но нас интересует устойчивость потока или вопрос того, какой результат получится при маленьких приращениях в скоростях автомобилей. Выражение (*) будет наложением экспоненциальных решений следующей формы где ип и а являются (комплексными) константами и система будет неустойчива, если скорости будут неограничены, то есть если есть любые решения, где действительная часть п положительна. Используя векторную систему обозначений, мы получим п(t) = ехр(at)v, п(t + Т) = аехр(аТ)ехр(at)v. Возвращаясь назад к выражению (*), мы получаем уравнение а ехр( аТ )ехр( at )v = Л( S -1 )exp( at )v, где 'О 0 ••• О 1Ч 10 — 00 s = 0 1 о о 0 0 1 О
Глава 10. Прикладные задачи 233 является матрицей «сдвига», которая при умножении на вектор слева, циклически переставляет элементы вектора. Мы можем убрать exp(ott) на каждой из сторон уравнения, чтобы получить а ехр( аТ )v = Л( S -1 )v, или что говорит о том, что и является собственным вектором матрицы S с собственным значением 1н—ехр(аТ). А Так как собственные значения S являются корнями N-ой степени из единицы, которые равномерно распределены по единичной окружности на комплексной плоскости и близко расположены друг к другу при большом значении N, то есть возможна неустойчивость всякий раз, когда 1+—ехр(аГ) А имеет модуль 1 для некоторого а с положительной действительной частью, то есть, всякий раз, когда может иметь форму exp(iG) - 1 для некоторого <хТ с положительной действительной частью. Появление неустойчивости зависит от значения произведения XT. Мы можем видеть это при построении графика для значений zexp(z), где z = аТ = iy - комплексное число на линии перехода Re z = 0 и при сравнении с графиками XT (ехв - 1) для различных значений параметра XT. >> syms у; expand(i*y* (cos(у) + i*sin(y))) ans = i*y*cos (y) -y*sin (y) >> ezplot(-y*sin(y), y*cos(y)# [-2*pi, 2*pi]); hold on » theta = 0:0.05*pi:2*pi; » plot(A/2)*(cos(theta) - 1)# A/2)*sin(theta)# '-');
234 MATLAB » plot(cos(theta) - 1, sin(theta), •:¦) » plotB*(cos(theta) - 1), 2*sin(theta), •--¦)/ » titleCiyeMiy} and circles \lainbda T(eA{i\theta}-l) ¦) >> hold off iyely и окружности к Т(е|8-1) 6 4 2 0 -2 -4 -6 / ! ч v^. J, \ -6-4-202468 х Здесь маленькая сплошная окружность соответствует XT = 1/2, и мы находимся как раз на пределе устойчивости, так как эта окружность не пересекает спираль, созданную zexp (z), где z - комплексное число на линии перехода Re z = 0, хотя она и подходит к спирали довольно близко. Точечные и пунктирные окружности, соответствуя XT = 1 или 2, действительно пересекают спираль, таким образом, они соответствуют неустойчивому транспортному потоку. Мы можем проверить эти теоретические предположения с помощью моделирования в программе Simulink. Мы приведем схему модели для программы Simulink и затем объясним ее. open_system traffic Параметр чувствительности Подсистема: различия скоростей автомобилей Относительные позиции автомобилей Начальные позиции автомобилей
Глава 10. Прикладные задачи 235 Здесь Subsystem (Подсистема) соответствует умножению на S - I и выглядит следующим образом: >> open_system 'traffic/Subsystem: computes velocity differences ¦ Вход 1 Большая часть модели похожа на пример из главы 8, за исключением того, что наша неизвестная функция (названная и), представляющая положения автомобилей, является векторнозначной, а не скалярнозначной. Основные отличия следующие. • Мы должны включить задержку времени реагирования, поэтому мы вставили блок Transport Delay (Задержка транспорта) из библиотеки блоков Continuous (Длительные) с параметром Time delay (Задержка времени) Т, установленным равным 0.5. • Параметр X отражается как значение увеличения в Sensitivity parameter (Параметр чувствительности) блока Gain (Увеличение) вверху справа. • Построение положений автомобилей не будет очень полезно, поскольку важно только их относительное расположение. Так, перед выводом положений автомобилей в блок Scope (Индикатор), помеченный как Relative car positions (Относительные положения автомобилей), мы вычли постоянную линейную функцию (соответствующую постоянному движению автомобилей на средней скорости), созданную блоком Ramp (Пилообразный сигнал) из библиотеки блоков Sources (Источники). • Мы использовали параметры в блоках Integrator (Интегратор), чтобы ввести начальные условия, вместо того, чтобы встроить их в блок. Это делает логическую структуру немного яснее. • Мы использовали возможность программы Simulink Subsystem (Подсистема). Если вы с помощью мыши добавите группу блоков и затем в программе Simulink выберете пункт Create subsystem (Создать подсистему) из меню модели Edit (Редактирование), то эта группа блоков будет сохранена как подсистема. Это полезно, если ваша модель довольна большая или если есть некоторая комбинация блоков, которую вы планируете использовать несколько раз. Наша подсистема отправляет вектор ив (S - I)u = Su - и. Блок Sum (Суммирование) (с одним из знаков, измененным на минус) используется для векторного вычитания. Чтобы смоделировать действие матрицы сдвига S, мы использовали блоки Demux (Разделитель) и Мих (Объединитель) из библиотеки блоков Signal Routing (Разводка сигналов). Блок Demux (Разделитель) с параметром Number of outputs (Число выходных данных), установленный
236 MATLAB равным [4/ 1], разделяет пятимерный вектор на пару, состоящую из четырехмерного вектора и скаляра (соответствующего последнему автомобилю). Затем мы изменяем их порядок и соединяем их вместе с помощью блока Мих (Объединитель), для которого параметр Number of inputs (Число входных данных) установлен равным [ 1, 4 ]. Когда модель собрана, ее можно выполнить с различными входными параметрами. Вы можете сами посмотреть на результаты в двух окнах блока Scope (Индикатор), но здесь мы выполнили моделирование из командной строки и построили результаты с помощью команды simplot, которая делает практически то же самое, что и блок Scope (Индикатор), но в обычном графическом окне среды MATLAB. Следующие изображения произведены с коэффициентом А = 0.8, который соответствует устойчивому потоку (хотя, честно говоря, мы позволили двум автомобилям пересечься друг с другом!): >> set_param('traffic/sensitivity parameter1, lGainl# '0.8'); [t, x] = sim(-traffic'); Переменная t хранит параметр времени, а переменная x содержит в своих первых пяти столбцах скорости автомобилей и положения автомобилей - во вторых пяти столбцах. В этом примере средняя скорость составляет 3.15. Сначала мы построим график для относительных положений автомобилей, а затем - график для скоростей. » relpos = х(:,6:10) - 3.15*t*ones(l,5); >> simplot(t# relpos), title('Relative Positions') >> axis([0, 20, 0, 1]), axis normal » simplot(t, x(:,l:5)), title('Car Velocities') » axis([0, 20, 3, 3.3])
Глава 10. Прикладные задачи 237 Как можно заметить, скорости колеблются, но, в конечном счете, сходятся к одному значению, а различия между автомобилями в итоге уменьшаются. С другой стороны, если X увеличивается при изменении «параметра чувствительности» в блоке Gain (Увеличение), расположенном вверху справа, скажем, с 0.8 до 2.0, то мы получаем следующий результат, который весьма обычен для случая с неустойчивостью: >> set_param( 'traffic/sensivity parameter1, 'Gain1, '2.01); >> [t, x] = sim('traffic1); >> relpos = x(:,6:10) - 3.15*t*onesA#5); >> simplot(t, relpos), title('Relative Positions1) » axis( [0, 20, -10, 10] ) » simplot(t, x(:,l:5)), title('Car Velocities') » axis([0, 20, -10, 10] )
238 MATLAB Мы рекомендуем вам вернуться и изменить модель (например, использовать параметр чувствительности, который обратно пропорционален расстоянию между автомобилями), и исследовать полученные результаты. Наконец, вы можете создать фильм с помощью следующего кода: >> elf reset » set(gcf, «Color1, 'White') >> clear M » theta a @:0.025:2)*pi; >> for j = l:length(t) plot(cos(x(j, 1:5)), sin(x(j, 1:5)), 'o'); axis([-l, 1, -1, 1] ) ; hold on; plot(cos(theta), sin(theta), 'r'); hold off axis equal; M(j) = getframe; end 1 0.5 -0.5 -1 / 1 1 i \ \ \ \ \ \ i ; / _y -1 -0.5 0.5
Глава 10. Прикладные задачи 239 Идея здесь заключается в том, что мы взяли круговую дорогу, чтобы радиус был равен 1 (в подходящих единицах) так, чтобы команда plot (cos (theta), sin (theta), 'г') строила красную окружность (представляющую дорогу) в каждом кадре фильма. На линии этой окружности автомобили показаны с помощью небольших перемещающихся окружностей. График, показанный выше, является последним кадром фильма. Вы можете просмотреть весь фильм, если введете команду movie (М) или movieview (M). Пробуйте сделать это! Мы должны отметить здесь, что необходимо рассмотреть один тонкий вопрос, чтобы создать правдоподобный фильм. А именно, нам необходимо, чтобы значения t были распределены равномерно. Иначе будет казаться, что автомобили перемещаются быстрее при больших шагах времени, и наоборот, движение автомобилей будет выглядеть медленнее при маленьких шагах времени. В режиме работы по умолчанию программа Simulink использует функцию решения дифференциальных уравнений переменного шага, основанную на команде среды MATLAB ode45, таким образом, элементы t окажутся размещены неравномерно. Мы исправили этот недостаток. Для этого мы открыли диалог Configuration Parameters (Параметры настройки), выбрав этот пункт меню в окне модели Simulation ¦ Configuration Parameters... (Моделирование ¦ Параметры настройки), и выбрали пункт Data Import/Export (Ввод/Вывод данных). В появившемся диалоге мы изменили значение параметра Output options (Настройки вывода) на Produce specified output only (Создавать только указанные выходные данные) с настройкой Output times (Времена выходных данных), равной [0:0.5:20]. Тогда модель будет выводить положения автомобилей только во времена, которые кратны 0.5, и представленная выше программа для среды MATLAB создаст фильм, состоящий из 41 кадра.
Практическое занятие С. Развитие навыков работы с программой MATLAB Задачи 5, 7, 14 и 15 несколько сложнее, чем другие. Задачи 8 и 9 требуют или использования функции simlp из программы Simulink или же применения набора инструментов Optimization (Оптимизация). Задача 11 а) требует использование набора инструментов Symbolic Math (Символьная математика), для других задач этот набор не нужен. Программа Simulink необходима для задач 12 и 13. 1. Капитан Пикард скрывается в квадратной арене, сторона которой равна 50 метров. Эта арена защищается силовым полем пятого уровня. К сожалению, кардессиане, которые стреляют в арену, обладают смертельным лучом, который может проникнуть через силовое поле. Точка падения смертельного луча получает 10 000 единиц смертельной радиации. Чтобы уничтожить капитана, требуется только 50 единиц. Все меньшие значения не оказывают никакого воздействия. Число единиц, которые приходят в точку (х, у), когда смертельный луч ударяет на высоте один метр над землей в точку (хд, у0), управляется закон обратного квадрата, а именно, 10000 4к((х-хоJ+(У-Уо)Г + 1) Датчики кардессиан не могут определить точного положения Пикарда, поэтому они стреляют в случайную точку на арене. (а) Используйте команду contour, чтобы отобразить арену после пяти случайных попаданий смертельного луча. Период полураспада радиации очень короток, поэтому можно предположить, что радиация исчезает почти мгновенно - только начальный взрыв может оказать какое-либо воздействие. Однако включите все пять ударов в ваше изображение, как на цейтраферной киносъемке. Как вы думаете, в каком месте арены капитану Пикарду следует прятаться? (б) Предположим, что Пикард стоит в центре арены. Кроме того, предположим, что кардессиане запускают смертельный луч 100 раз, каждый выстрел попадает в случайную точку на арене. Выживет ли Пикард? (в) Запустите повторно предыдущий «эксперимент» 100 раз и оцените вероятность, что капитан Пикард может пережить атаку из 100 выстрелов. (г) Повторите предыдущий пункт, но на этот раз поместите капитана на расстоянии 3/4 длины одной из сторон арены (то есть в точку х = 37.5,у = 25, если координаты арены удовлетворяют условиям 0 < х < 50,0 < у <). (д) Заново выполните моделирование для случаев, когда капитан находится у одной из сторон, и, наконец, в углу арены. Какой вывод напрашивается после этих экспериментов?
Практическое занятие С. Развитие навыков работы с программой MATLAB 241 2. Рассмотрите счет, на котором хранится М долларов и для которого выплачивается ежемесячный процент /. Предположим, что, начиная с определенного момента, сумма S вкладывается ежемесячно и не проводятся никакие снятия средств. (а) Для начала предположите, что S = 0. Используя задачу из 10 главы, посвященную залоговым платежам как пример, получите уравнение, связывающее /, М, число прошедших месяцев п и общее количество средств Т на счете через п месяцев. Предположите, что процент отдается в последний день месяца, а общая сумма Т вычисляется на следующий день после того, как отдается процент по кредиту. (б) Теперь предположите, что М = 0, что S вкладывается в первый день месяца и что, как прежде, проценты выплачиваются в последний день месяца, а общая сумма Т вычисляется на следующий день после выплаты процентов. Напомним еще раз, используя прикладную задачу, посвященную закладу в качестве примера, получите уравнение, связывающее /, 5, число прошедших месяцев п и общую сумму Тна счете через п месяцев. (в) Объединив последние две модели, получите уравнение, связывающее все величины М, 5,/, пи Т, теперь, конечно, приняв, что есть начальная сумма на счете (М) и проводятся ежемесячные взносы E). (г) Если ежегодная процентная ставка равна 5% и не производятся никакие ежемесячные вклады, то сколько лет потребуется, чтобы удвоить ваш начальный денежный капитал? Что, если ежегодная процентная ставка составит 10%? (д) В этом и следующей пунктах задачи примите, что нет никакого начального капитала. Допустим, ежегодная процентная ставка составляет 8%. Сколько вы должны вносить ежемесячно, чтобы стать миллионером через 35 лет (целая карьера)? (е) Если процентная ставка остается, как в предыдущем пункте и вы можете позволить себе вносить каждый месяц только 300$, то как долго вам придется работать, чтобы записаться в миллионеры? (ж) Вы выигрываете в лотерею и становитесь обладателем 100000$. У вас есть два варианта: взять эти деньги, заплатить налоги и вложить оставшиеся средства; или получать 100000/240$ ежемесячно в течение 20 лет, вкладывая средства, которые будут оставаться после уплаты налогов. Предположите, что неожиданная удача 100000$ будет стоить вам 35 000$ федеральных и местных налогов и что меньшая ежемесячная выплата потребует отдать только 20% на налоги. В каком случае вы окажетесь более обеспеченными через 20 лет? Примите в этой задаче ежегодную процентную ставку равной 5%. (з) Как показывает история, банки платили примерно 5%, в то время как фондовая биржа имела тенденцию выдавать в среднем 8% за 10-летний период. Таким образом, части (д) и (е) связаны больше с вложением, чем с получением. Но предположите, что рынок за 5-летний период выдает 13%, 15%, -3%, 5% и 10% в пяти
242 MATLAB последовательных годах, а затем повторяет цикл. (Обратите внимание, что среднее [арифметическое] значение равно 8%, хотя среднее геометрическое было бы здесь более подходящим.) Предположите, что 50000 $ вкладываются в начале 5-летнего рыночного периода. Насколько возрастет эта сумма через 5 лет? Теперь повторно вычислите еще четыре раза, предполагая, что вы начинаете цикл в начале второго года, третьего года и т.д. Какой из этих вариантов приведет к лучшим/худшим результатам? Можете ли вы объяснить, почему? Сравните результаты со счетом с фиксированной процентной ставкой 8%. Примите простой ежегодный процент. Повторите эти пять вычислений с вложениями, предполагая, что в начале каждого года вносится 10000$. Еще раз проанализируйте результаты. 3. Тони Гвинн обладал средним уровнем подач за всю его деятельность равным 338. Это означает, что из каждой 1000 подач 338 были для него удачными. (В этом упражнении мы не будем учитывать некоторые вещи, которые не влияют на результат игры.) За год он накопил в среднем 500 официальных подач. (а) Спроектируйте моделирование Монте-Карло для одного года из карьеры Тони. Запустите модель. Каков средний уровень Тони? (б) Теперь смоделируйте 20-летнюю карьеру. Примите 500 официальных подач каждый год. Каков у Тони лучший средний уровень за карьеру? Каков его худший уровень? Каково среднее значение за всю его деятельность? (в) Теперь запустите моделирование его 20-летней карьеры еще четыре раза. Ответьте на вопросы из части б) для каждого из этих четырех моделирований. (г) Вычислите среднее число для пяти средних значений за его деятельность, которые вы вычислили в частях б) и в). Как вы считаете, что получилось, если бы вы выполнили 20-летнее моделирование 100 раз и нашли бы среднее число для средних значений за всю его деятельность для всех 100 моделирований? Следующие четыре задачи показывают примеры некоторых основных навыков программирования в среде MATLAB. 4. Для положительного целого числа п, пусть А(п) будет матрицей размером пх п, элемент которой в положении (if) равен а^=\/A+j-\). Например, ЛC) = 1 i i 1 1 1 2" T  1 1 1 ITT Все собственные значения А(п) являются действительными числами. Создайте М-файл с программой, которая выводит наибольшее собственное значение матрицы АE00), без какого-либо постороннего результата. (Совет: М-файл может требовать довольно много времени на выполнение, если вы будете использовать один цикл внутри другого цикла, чтобы определить А. Пробуйте избежать этого!)
Практическое занятие С. Развитие навыков работы с программой MATLAB 243 5. Of Напишите М-файл с текстом программы, которая рисует образец мишени с центральной красной окружностью, которая окружена чередующимися круглыми полосами (кольцами) белого и черного цветов, скажем, десятью полосами каждого цвета. Убедитесь, что на получившемся рисунке отображаются окружности, а не эллипсы. (Совет: одним из способов закрасить область между двумя окружностями черным цветом состоит в том, чтобы закрасить всю внутреннюю часть внешней окружности черным цветом, а затем закрасить внутреннюю часть внутренней окружности белым цветом.) 6. Среда MATLAB содержит функцию Icm, которая находит наименьшее общее кратное для двух чисел. Напишите М-файл mylcm.m для функции, которая находит наименьшее общее кратное произвольного числа положительных целых чисел, которые можно задать как отдельные аргументы или в векторе. Например, обе команды my Icm D, 5, 6) и mylcxn ( [4 5 6] ) должны выдать ответ 60. Программа должна показывать понятное сообщение об ошибке, если любой из входных параметров не является положительным целым числом. (Подсказка: для трех чисел вы можете использовать функцию Icm, чтобы найти наименьшее общее кратное т для первых двух чисел, затем используйте функцию Icm еще раз, чтобы найти наименьшее общее кратное значения т и третьего числа. Ваш М-файл поможет обобщить этот подход.) 7. ft Напишите М-файл для функции, которая принимает в качестве входного параметра строку, содержащую название текстового файла и создает гистограмму числа вхождений каждой буквы от А до Z в файле. Пробуйте подписать рисунок и оси так, чтобы результаты можно было легко понять. 8. Рассмотрите следующую задачу линейного программирования. Джейн Доу баллотируется на пост Специального уполномоченного графства. Она хочет лично собрать избирателей в четырех главных городах графства: Готем, Метрополис, Оз и Ривер Сити. Она должна выяснить, сколько домов (частные дома, квартиры, и т.д.) необходимо посетить в каждом городе. Ограничения следующие. а) Она намеревается оставить брошюру кампании в каждом доме. У нее в наличии есть только 50000 брошюр. б) Затраты на передвижение для каждого дома следующие: 0.50 $ на каждый дом в Готеме и Метрополисе, 1 $ - городе Оз и 2 $ в - Ривер Сити. У нее в наличии есть 40000 $. в) Время (в среднем), которое требуется на посещение каждого дома, следующее: 2 минуты в Готеме, 3 минуты в Метрополисе, минута в городе Оз и 4 минуты в Ривер Сити. Ее запас времени составляет 300 часов. г) В силу политических обстоятельств Джейн знает, что она не должна посетить больше домов в Готеме, чем в Метрополисе, и что общее число посещенных домов в Метрополисе и Озе не должно превысить число домов, которые она посетит в Ривер Сити.
244 MATLAB д) Джейн ожидает получить вклады на кампанию в течение ее посещений в среднем по одному доллару от каждого дома в Готеме, четверть доллара от дома в Метрополисе, пятьдесят центов от жителей Оза и три доллара от людей в Ривер Сити. Она должна собрать, по крайней мере, 10000 $ за всю поездку. Цель Джейн состоит в том, чтобы увеличить до предела число сторонников (тех, кто, скорее всего, проголосует за нее). По ее оценке, для каждого дома, который она посещает в Готеме, шансы, что она получит сторонника, равны 0.6, а вероятности в Метрополисе, Озе и Ривер Сити равны соответственно 0.6, 0.5 и 0.3. (а) Сколько домов она должна посетить в каждом из этих четырех городов? (б) Предположим, что она может удвоить время, выделенное на посещения. Что тогда будет ключевым фактором, определяющим количество посещений? (в) Но предположите, что дополнительное время (в предыдущем пункте) также позволяет ей удвоить общую сумму полученных вкладов. Что теперь определяет число посещений? 9. Рассмотрим следующую задачу линейного программирования. Известный футбольный тренер Джо Глибб пытается решить, сколько часов ему необходимо провести с каждым участником его наступательного блока в течение будущей недели, то есть, с защитником, с бегунами, с принимающими и с судьями на линии. Ограничения в этом случае следующие. а) Число часов, доступных для Джо в течение недели, равно 50. б) Джо полагает, что ему необходимо 20 очков, чтобы выиграть следующую игру. Он оценивает, что за каждый час, который он потратит на защитника, он может ожидать отдачу в 0.5 очка. Величины для бегунов, принимающих и судей на линии равны 0.3, 0.4 и 0.1. в) Несмотря на их огромный размер, игроки весьма ранимы. За каждый час с защитником Джо, вероятно, может критиковать его один раз. Значения частоты критики в час для других трех групп следующие: 2 для бегунов, 3 - для принимающих и 0.5 для судей на линии. Джо полагает, что он может позволить только 75 критических замечаний в неделю прежде, чем он потеряет управление над игроками. г) Наконец, игроки - это, в своем роде, те же примадонны, которые соперничают друг с другом. Из-за этого Джо должен провести точно такое же число часов с бегунами, что и с принимающими; по крайней мере, так же много часов с защитником, как с бегунами и принимающими вместе, и, по крайней мере, так же много часов с принимающими, как он проводит с судьями на линии. Джо волнуется, что его собираются уволить в конце сезона независимо от результата игры, таким образом, его первичная цель состоит в том, чтобы увеличить до предела его удовольствие за неделю. Он оценивает, что по скользящей шкале от 0 до 1 он получит 0.2 единицы личного удовольствия за каждый час, проведенный с защитником. Значения для бегунов, принимающих и судей на линии равны соответственно 0.4, 0.3 и 0.6.
Практическое занятие С. Развитие навыков работы с программой MATLAB 245 (а) Сколько часов Джо должен провести с каждой группой? (б) Предположим, что для победы в следующей игре команде необходимо только 15 очков. Тогда сколько часов необходимо Джо? (в) Наконец, предположите, что, несмотря на то, что необходимо только 15 очков, эта группа становится весьма беспокойной, и он может позволить только 70 критических замечаний на этой неделе. Получит ли Джо наилучший результат за неделю? 10. Эта задача, предложенная нам нашим коллегой Томом Антонсеном, касается электрического контура, один из компонентов которого ведет себя нелинейно. Рассмотрите контур на Рис. С. 1. В отличие от резистора, диод является нелинейным элементом - он не подчиняется закону Ома. На самом деле, поведение диода определяется формулой i = Ioexp(VD/Vr),(C.l) Резистор Батарея Диод v Рис. С. 1. Нелинейный контур где г - это ток через диод (который одинаков как в диоде, так и в резисторе согласно закону Кирхгофа о токе), VD - это напряжение на диоде, 10 представляет ток утечки диода и VT = kT/e, где k является постоянной Больцмана, Т отражает температуру диода, а е- это элементарный электрический заряд. Теперь, согласно закону Ома для резистора, мы также знаем, что VR = iR, где VR является напряжением на резисторе, a R является сопротивлением резистора. Но по закону Кирхгофа о напряжении мы также получаем VR = Vo - V^ Таким образом, мы получаем второе уравнение, связывающее ток и напряжение диода, а именно, i=(V0-VD)/R.(C2) Обратите внимание, что теперь, когда выражение (С.2) говорит, что i является убывающей линейной функцией от VD со значением Vo/R, когда VD равно нулю. В то же самое время (С.1) говорит, что i - это экспоненциально возрастающая функция от VD, начинающаяся в Iq. Поскольку обычно Шо < V& то две получающиеся кривые (для i как функции от VD) должны один раз пересечься. Исключая i
246 MATLAB из этих двух уравнений, мы видим, что напряжение на диоде должно удовлетворять трансцендентному уравнению ИЛИ VD=Vo-RIoexp(VD/VT). (а) Подходящими значениями для электрических постоянных являются Vo = 1.5 В, R = 1000 Ом, 10 - 10-5 А и VT = 0.0025 В. Используйте команду fzero, чтобы найти напряжение VD и ток i в этом контуре. (б) В оставшейся части задачи мы предположим, что напряжение Vo на батарее и на сопротивлении R резистора неизменно. Но допустим, что мы можем изменить электрические свойства диода. Например, предположите, что 10 будет меньше в два раза. Что произойдет с напряжением? (в) Предположим, что вместо того, чтобы уменьшать 1^ мы разделим на два значение V-p. Как это повлияет на величину VJ (г) Предположим, что и значение I& и значение VT уменьшаются в два раза. Что получится? (д) Наконец, мы хотим исследовать поведение напряжения, если и I& и VT уменьшаются до нуля. Для определенности предположите, что мы устанавливаем 10 = 10'5я, VT = 0.0025* и пусть х-* 0. Вычислите решение для х = 10*, j = 0,...,5. Затем с помощью команды loglog отобразите график полученных значений напряжения как функции от Iq. К какому выводу вы пришли? 11. Эта задача основана на задачах «Математическая генетика» и «Маятник 360°» из 10 главы. Ранее рост вида был смоделирован на основе разностного уравнения. В этой задаче мы будем моделировать прирост численности вида с помощью дифференциального уравнения, родственного второй задаче, упомянутой выше. На самом деле мы можем задать модель дифференциального уравнения для логистического роста численности вида х как функцию от времени t с помощью следующего уравнения ¦X = a:A-jc) = jc-jc2, (C.3) где X обозначает производную х относительно I Мы относимся к х как к части некоторой наибольшей возможной численности. Преимущество этой непрерывной модели по сравнению с дискретной моделью в главе 10 состоит в том, что мы можем получить значение численности в любой точке во времени (не только на целочисленных промежутках). (а) Дифференциальное уравнение (С.З) решается в любом курсе для начинающих, посвященном обыкновенным дифференциальным уравнениям, но вы можете легко
Практическое занятие С. Развитие навыков работы с программой MATLAB 247 это сделать с помощью команды dsolve из среды MATLAB. (Найдите синтаксис для этой команды в оперативной справке.) (б) Теперь найдите решение, предполагая, что начальное значение х0 = х@) для х. Используйте значения х0 = 0, 0.25 ... 2.0. Постройте график решения и используйте этот рисунок, чтобы подтвердить утверждение: «Независимо от условия х0 > 0, решение (С.З) в долгосрочном плане стремится к постоянному решению x(t) = 1». Логистическая модель предполагает две основных возможности прироста численности: во-первых, в идеале численность расширяется со скоростью, пропорциональной ее текущему значению (то есть для экспоненциального роста это соответствует переменной х на правой стороне уравнения (С.З)); и во-вторых, из-за взаимодействий между членами вида и естественных ограничений роста беспрепятственный экспоненциальный рост сдерживается логистическим условием, представленным с помощью переменной -л* в выражении (С.З). Теперь предположите, что есть два вида x(t) и y(t)f которые соперничают за одни и те же ресурсы, необходимые для выживания. Тогда появится другая отрицательная переменная в дифференциальном уравнении, которая отражает взаимодействие между видами. Обычная модель предполагает, что она пропорциональна приросту этих двух видов и чем больше коэффициент пропорциональности, тем наблюдается более серьезное взаимодействие, так же, как и большее итоговое замедление прироста численности. (в) Ниже показана обычная пара дифференциальных уравнений, которая моделирует рост численности двух соперничающих видов x(t) и y(t): = x-x2 -0.5ху . (С4) = y-y2-0.5xy. Команда dsolve может решить много пар обыкновенных дифференциальных уравнений, особенно линейных. Но сочетание квадратных членов в (С.4) делает эту систему уравнений нерешаемой символьно, таким образом, мы должны использовать средство численного решения ОДУ, как мы делали в прикладной задаче с маятником. Используя команды из этой задачи в качестве примера, постройте график кривых численного решения для системы (С.4) со следующими исходными данными = 0:1/12:13/12 = 0:1/12:13/12. (Подсказка: используйте команду axes, чтобы ограничить ваш вид квадратом 0 L хуу<> 13/12.) (г) График, который вы построили, называют фазовым видом системы. Объясните его. Объясните долгосрочное поведение любого распределения численности вида, которое начинается только с присутствия одного вида. Свяжите это с
248 MATLAB пунктом (б). Что случится в долгосрочной перспективе, если оба вида присутствуют изначально? Есть ли начальное распределение численности, которое остается неизменным? Что это за распределение? Свяжите эти числа с моделью (С.4). (д) Теперь замените в модели 0.5 на 2, то есть рассмотрите новую модель х( t) = х - х2 - 2ху (С5) Нарисуйте фазовый вид. (Используйте те же самые исходные данные и тот же квадрат просмотра.) Ответьте на вопросы из пункта (б). Видите ли вы особую траекторию решения, которая выходит примерно из начала координат и подходит к определенной постоянной точке? Видите ли вы другую траекторию, начинающуюся вверху справа и идущую к постоянной точке? Что происходит со всеми распределениями численности вида, которые не начинаются на этих траекториях? (е) Объясните, почему модель (С.4) называют «мирное сосуществование», а модель (С.5) называют «судный день». Теперь объясните эвристически, почему изменение коэффициента от 0.5 до 2 превращает мирное сосуществование в судный день. 12. Щ* Постройте модель для программы Simulink, соответствующую следующему уравнению маятника O (O98i((O) (C.6) из задачи «Маятник 360°», рассмотренной в главе 10. Вам потребуется блок Trigonometric Function (Тригонометрическая функция) из библиотеки Math (Математика). Используйте вашу модель, чтобы заново построить некоторые из фазовых видов. 13. Щ Как вы знаете, Галилео и Ньютон обнаружили, что все тела около поверхности Земли падают одинаковым ускорением g из-за действия силы тяжести, приблизительно равной 32.2 фут/сек2. Однако на тела также действуют силы, вызванные сопротивлением воздуха. Если мы примем во внимание как силу тяжести, так и сопротивление воздуха, то движущийся шар можно будет смоделировать с помощью следующего дифференциального уравнения * = [0,-g]-c|x|i:. (C.7) Здесь х - функция от времени t - является вектором, определяющим положение шара (первая координата измеряется горизонтально, а вторая - вертикально), X является вектором скорости шара, X должен быть стиль, является ускорением шара, |х является модулем скорости, то есть, быстротой движения шара. Постоянная с зависит от особенностей поверхности, массы шара и плотности воздуха. (Мы пренебрегаем подъемной силой, вызываемой вращением шара,
Практическое занятие С. Развитие навыков работы с программой MATLAB 249 которое также может играть главную роль в некоторых случаях, например, при исследовании кривой пути шара, а также пренебрегаем силами, вызванными ветровыми потоками.) Для бейсбольного мяча постоянная с оказывается приблизительно равной 0.0017, предполагая, что расстояния измеряются в футах, а время измеряется в секундах. (Смотрите, например, 18 главу «Шары, броски и подачи» из книги «Towing Icebergs, Falling Dominoes, and Other Adventures in Applied Mathematics» (Буксирование айсбергов, падение домино и другие приключения в прикладной математике), Роберт Бэнкс, издательство Университета Принстона, Принстон, 1998.) Постройте модель для программы Simulink, соответствующую уравнению (С.7), и используйте эту модель, чтобы изучить траекторию отбитого бейсбольного мяча. Вот несколько советов. Представьте X, X и х как векторные сигналы, к которым присоединяются два блока Integrator (Интегратор). Величина X, согласно (С.7), должна быть получена из блока Sum (Суммирование) с двумя векторными входными параметрами. Один параметр должен быть блоком Constant (Постоянная) с векторным значением [0, -32.2], представляя силу тяжести, а другой должен представлять модуль на правой стороне уравнения (С.7), вычисленный на основе значения X. Вы должны быть в состоянии изменить один из параметров, чтобы узнать, что получится как с учетом, так и без учета сопротивления воздуха (случаи с = 0.0017 и с = 0 соответственно). Соедините результат с блоком XY Graph (График XY), с параметрами x-min = 0, y-min = 0,x-max = 500, y-max = 150, таким образом, вы можете увидеть путь шара до конца, на расстоянии 500 футов от исходного положения и до высоты 150 футов. (а) Пусть х@) = [0.4] и х@) = [80, 80]. (Это соответствует шару, начинающему движение в t = 0 из исходного положения, 4 фута от основания, с горизонтальной и вертикальной составляющими его скорости равными 80 футов в секунду. Это соответствует скорости мяча приблизительно 77 миль в час, которая является весьма правдоподобной.) Как далеко шар переместится (вы можете это приблизительно увидеть с помощью блока XY Graph (График XY)) прежде, чем он достигнет основания с учетом и без учета сопротивления воздуха? Сколько времени необходимо, чтобы шар достиг основания, и как быстро шар будет перемещаться (опять необходимо рассмотреть два случая - с учетом и без учета сопротивления воздуха)? (б) Предположим, что игра проходит в Денвере, Колорадо, где из-за разжижения атмосферы вследствие большой высоты над уровнем моря с составляет всего лишь 0.0014. Как далеко шар переместится в этом случае (используйте ту же самую начальную скорость, что и в пункте (а))? (в) (Это не задача для среды MATLAB.) С помощью сравнения ваших ответов на пункты (а) и (б) оцените, как высота над уровнем моря могла бы повлиять на среднее число отбитых мячей и на среднее число заработанных очков команды Колорадо Рокис.
250 MATLAB 14. Ot Напишите М-файл для функции (без аргументов и результатов), который просматривает текущую папку, находит последний измененный М-файл и открывает его в редакторе/отладчике. Если текущая папка не содержит никаких М-файлов, то ваш М-файл должен создать сообщение об ошибке. В идеальном случае, вы должны попробовать написать М-файл таким образом, чтобы он работал как в операционной системе Windows, так и в операционной системе UNIX, но, по крайней мере, чтобы он работал с вашей собственной операционной системой. 15. 1ЙГ Рассчитайте последовательность комплексных чисел, созданную из начального значения z0 по правилу 2^+1 = zn2 - 0.75. Для некоторых значений Zo последовательность чисел уходит в бесконечность по мере возрастания п, но для других значений г0 эта последовательность всегда будет находиться в ограниченной области. Границу набора, состоящего из последних значений Z& называют набором Джулии для функции J{z) = z2 - 0.75. Используйте функцию image или im- agesc, чтобы нарисовать изображение этого набора Джулии. (Совет: набор Джулии приводит к неверным результатам в области, где действительная часть z0 находится между -2 и 2, а мнимая часть z0 - между -1.5 и 1.5. Создайте сетку для значений z0 в пределах этого прямоугольника (мы предлагаем использовать массив примерно 300 х 100) и вычислите значения zb z2, ..., ztl для некоторого п. Выделите точку каждого Zq цветом согласно тому, насколько большим получилось значение z,,. Чем больше вы делаете п, тем более точным (и интересным) будет изображение, но в этом случае вычисления потребуют больше времени, так что начните с относительно маленького значения п и попробуйте увеличить его.
ГЛАВА 11 . Разрешение проблем В этой главе мы предлагаем советы, связанные с некоторыми распространенными затруднениями, с которыми вы можете столкнуться. Мы также перечисляем и описываем самые обычные ошибки, которые делают пользователи среды MATLAB. Наконец, мы предлагаем немного простых, но полезных методик отладки текстов программ ваших М-файлов. Обшие ошибки Ошибки проявляются различными способами: появляется совершенно неожиданный или явно неправильный результат; среда MATLAB создает сообщение об ошибке (или, по крайней мере, предупреждение); среда MATLAB отказывается обработать введенную строку; то, что работало ранее, перестает работать; или, в худшем случае, компьютер перестает отвечать. К счастью, эти трудности часто вызываются несколькими легко распознаваемыми и исправляемыми ошибками. Далее мы приводим описание некоторых распространенных ошибок вместе с предположением вероятных причин, с предложениями возможных решений и с пояснительными примерами. Мы также обращаемся к местам из этой книги, где обсуждаются связанные вопросы. К общим ошибкам относятся следующие виды ошибок: • Неправильный или неожиданный результат; • Ошибки синтаксиса; • Ошибки написания; • Сообщение об ошибке или предупреждение при построении графиков; • Сохраненный ранее М-файл вычисляется по-другому; • Компьютер не отвечает. Неправильный или неожиданный результат Есть много возможных причин для этой ошибки, но они, вероятно, будут среди следующих. ПРИЧИНА: Не выполнено очищение или переустановка переменных. РЕШЕНИЕ: Очистите или присвойте начальные значения для переменных перед их использованием, особенно при продолжительном сеансе работы. °ЗР Смотрите тему «Переменные и присваивание» в главе 2. ПРИМЕР: предположим, что вы создаете цикл, наподобие следующего
252 MATLAB >> for i = 1:10 end и позже в вашем сеансе работы вы вводите комплексное число 2 + 1. Тогда окажется, что на самом деле вы ввели число 12, поскольку в конце цикла переменная i становится равной 10. Чтобы восстановить первоначальное значение переменной V-1, вы должны набрать clear i. ПРИЧИНА: Противоречивые определения. РЕШЕНИЕ: Не используйте одно и то же название для двух различных функций или переменных и, в особенности, не используйте названия любой из встроенных функций среды MATLAB. Вы можете случайно перекрыть один из встроенных М-файлов среды MATLAB либо вашим собственным М-файлом с тем же самым названием, либо переменной (включая, возможно, встраиваемую или безымянную функцию). Когда получается неожиданный результат и вы считаете, что причиной этого могли быть противоречивые определения, то полезно использовать команду which, чтобы узнать, к какому М-файлу, функции или переменной на самом деле обращается написанная программа. Эта ошибка проявилась в предыдущем примере, ниже показан еще один, возможно, более выразительный пример. ПРИМЕР: >> plot = gcf; >> х = -2:0.1:2; >> plot(x, x.A2) ??? Subscript indices must either be real positive integers or logicals. Где ошибка? Конечно, команда plot была перекрыта переменной с таким же названием. Вы могли бы обнаружить это с помощью >> which plot plot is a variable. Если вы наберете clear plot и выполните команду plot снова, то вы получите изображение желаемой параболы. Более тонкий пример мог бы получиться, если бы вы сделали так сознательно, не думая, что вы будете использовать команду plot, а затем вызвали бы некоторый другой графический М-файл, который использует эту программу косвенно. ПРИЧИНА: Затирание переменной axis. РЕШЕНИЕ: Сохраняйте результат, который вы намереваетесь использовать в дальнейших вычислениях, в переменных с различными именами. Если в некоторый момент сеанса работы вы решаете, что вам необходимо обратиться к предшествующему результату, для которого не была введена переменная
Глава 11. Разрешение проблем 253 с собственным именем, тогда присвойте переменной результата название и выполните команду снова. (Чтобы повторно вызвать команду для редактирования, можно использовать клавишу |[TJ или окно Command History (История команд.) Не полагайтесь на переменную ans, так как эта переменная, вероятно, будет перезаписана прежде, чем вы выполните команду, которая ссылается на предшествующий результат. ПРИЧИНА: Неправильное использование встроенных функций. РЕШЕНИЕ: Всегда используйте названия встроенных функций точно так, как среда MATLAB определяет их. Всегда заключайте входные параметры в круглые скобки, а не в квадратные и не в фигурные скобки, всегда перечисляйте входные параметры в необходимом порядке. и^3 Смотрите темы «Управление переменными» и «Разрешение проблем» в главе 2. ПРИЧИНА: Невнимание к старшинству арифметических действий. РЕШЕНИЕ: Используйте круглые скобки щедро и правильно при вводе арифметических или алгебраических выражений. ПРИМЕР: Программа MATLAB, как любой калькулятор, сначала выполняет действия со степенями, затем делит и умножает и, наконец, складывает и вычитает, если другой порядок не задан с помощью круглых скобок. Так, если вы пытаетесь вычислить 52/3 - 25/ B*3), набирая » 5А2/3 - 25/2*3 ans = -29.1667 ответ, который среда MATLAB создает, не похож на то, что вы ожидали, потому что 5 возводится в степень 2 прежде, чем выполняется деление на 3, а 25 делится на 2 перед умножением 3. Ниже показано правильное вычисление: » 5А B/3) - 25/B*3) ans = -1.2426 Ошибки синтаксиса ПРИЧИНА: Несогласованные круглые скобки, кавычки, фигурные скобки или квадратные скобки. РЕШЕНИЕ: Просмотрите тщательно введенную строку, чтобы найти потерянный или лишний разделитель. Среда MATLAB обычно ловит ошибки этого вида. Кроме того, Рабочий стол среды MATLAB автоматически выделяет соответствие разделителей, когда вы набираете текст программы, и выделяет цветом введенные строки (выражения, заключенные в одинарных кавычках) так, чтобы вы могли видеть, где они начинаются и где заканчиваются. Однако в командном окне среды MATLAB 5 и более ранних версий вам придется добиваться соответствия разделителей вручную.
254 MATLAB ПРИЧИНА: Неправильные разделители: использование круглых скобок вместо квадратных, или наоборот, и тому подобное. РЕШЕНИЕ: Вспомните основные правила о разделителях в среде MATLAB. Круглые скобки используются и чтобы группировать арифметические выражения, и чтобы заключить входные параметры для команды среды MATLAB, для М-файла или для встраиваемой функции. Они также используются, чтобы обратиться к элементу в матрице. Квадратные скобки используются, чтобы определить векторы или матрицы. Знаки одинарной кавычки используются, чтобы определить строковые переменные. ПРИМЕР: Следующий пример показывает, что может получиться, если вы не будете следовать этим правилам: » X = -1:0.01:1; I Error: Unbalanced or misused parentheses or brackets. » A = @, 1, 2) ??? A = @, 1, 2) I Error: Incomplete or misformed expression or statement. Эти примеры довольно просты для понимания: в первом случае подразумевалось X A), а во втором случае необходимо вводить А = [ 0, 1# 2]. Но теперь посмотрите на более хитрый пример: >> abs 3 ans = 51 Здесь нет никакого сообщения об ошибке, но если вы посмотрите внимательно, то обнаружите, что среда MATLAB вывела модуль для значения 51, а не для 3. Объяснение следующее: каждый раз, когда команда среды MATLAB сопровождается пробелом и за ним следует входной параметр команды (например, clear x), то параметр всегда истолковывается как строка. Таким образом, среда MATLAB восприняла 3 не как число 3, а как строку ¦ 3 ¦! И можно обнаружить: » charE1) ans = 3
Глава 11. Разрешение проблем 255 Другими словами, в схеме кодирования среды MATLAB строка ¦ 3 ¦ сохраняется как число 51, вот почему в результате вычисления abs 3 (или также abs (¦ 3 ¦)) получается модуль 51. Фигурные скобки используются не так часто, как круглые или квадратные скобки, и обычно они не требуются новичкам. Их главное использование связано с матрицами элементов. Например, если вы хотите, чтобы М-файл получал изменяющееся число входных параметров или создал переменное число результатов, тогда эти значения сохраняются в матрицах элементов и varargout, а фигурные скобки используются, чтобы обратиться к ячейкам этих матриц. Так же case иногда используется с фигурными скобками в середине конструкции switch. Если вы хотите построить массив из строк, тогда это следует делать с использованием фигурных скобок, поскольку, когда со строками используются другие скобки, это истолковывается как объединение. ПРИМЕР: » {"а1, ¦!>¦} ans = •а1 'Ь1 » ['а1, 'Ь1 ] ans = ab ПРИЧИНА: Неверное использование арифметических символов. РЕШЕНИЕ: Когда вы сталкиваетесь с синтаксической ошибкой, внимательно проверьте вашу введенную строку на присутствие ошибок, допущенных при наборе команд. ПРИМЕР: Если пользователь, намереваясь вычислить выражение 2*-4, неосторожно набирает символы, то может получиться следующий результат » 2 - * 4 ??? 2 - * 4 Error: Unexpected MATLAB operator. Ошибки написания ПРИЧИНА: Использование прописных букв вместо строчных в командах среды MATLAB или неправильное написание команды. РЕШЕНИЕ: Исправьте написание.
256 MATLAE Рассмотрите следующие случайные ошибки написания. ПРИМЕР: >> Sin(pi/2) ??? Undefined command/function 'Sin1. » ffzero«a(x) xA2 - 3, 1) ??? Undefined command/function 'ffzero1. » fzero(@(x) x*2 - 3, 1) ans = 1.7321 Сообщения об ошибках или предупреждения при построении графиков ПРИЧИНА: Есть несколько возможных объяснений, но обычно ошибка заключается в неправильном типе входного параметра для выбранной команды построения. РЕШЕНИЕ: Внимательно относитесь к примерам из оперативной справки команды построения и обращайте внимание на сообщения об ошибках или предупреждения. ПРИМЕР: >> X = -3:0.05:3; » plot(X, X.M1/3)) Warning: imaginary parts of complex X and/or Y arguments ignored. /3 Рис. 11.1. Ложный графику = x1 Рис. 11.1 не является графиком функции у = х1/3 на промежутке -3 < х < 3. В действительности, график справа от начала координат выглядит верно, но слева от начала координат график, конечно, неправильный. Предупреждение дает ключ
Глава 11. Разрешение проблем 257 для нахождения ошибки. На самом деле получилось так, что среда MATLAB строит действительную часть х1/3, но для другой ветви многозначной функции, не той, которая нужна нам. Среда MATLAB воспринимает х1/3 для отрицательного х как значение [A + V3i)/2]|x|l/3. Чтобы исправить эту ошибку, мы должны определить функцию в среде MATLAB более аккуратно. Правильный график (Рис. 11.2), можно построить с помощью следующей команды » plot(X/ sign(X) .*abs(X) . Рис. 11.2. Правильный графику = х1 Ранее сохраненный М-файл вычисляется по-другому Одна из самых неприятных ошибок, с которой вы можете столкнуться, происходит, когда сохраненный ранее, проверенный М-файл при открытии в новом сеансе работы не вычисляется или вычисляется неправильно. ПРИЧИНА: Изменена последовательность вычислений или не выполнены присвоения начальных значений переменным. РЕШЕНИЕ: Не забудьте очистить или присвоить начальные значения переменным, которые не являются входными параметрами для М-файл а. ПРИМЕР: Эта ошибка видна из следующей простой, но плохо продуманной, программы. Чтобы вычислить п! (n-факториал), пользователь пишет следующий текст для М-файла: %% computing n! for k = 1:п f = f*k; end f предполагая, что будет присвоено начальное значение f = 1 вне этой программы, при выборе п. Если пользователь не выполнит присвоение начального 9-1605
258 MATLAB значения f во второй раз перед выполнением этих операций, то его ожидает неприятное удивление. Видите ли вы, почему? Компьютер не отвечает ПРИЧИНА: Среда MATLAB занята очень большими вычислениями или произошла какая-то другая неприятность, которая привела к тому, что система оказалась не в состоянии отвечать на действия пользователя. Возможно, вы используете массив, который является слишком большим для памяти вашего компьютера. РЕШЕНИЕ: Прервите вычисление с помощью комбинации клавиш I ctrl \цО\. Если сложности вызывает злоупотребление машинной памятью, то пробуйте заново выполнить ваше вычисление, используя меньшие массивы, например, при использовании меньшего количества точек сетки в трехмерном графике или при разделении большого вычисления с векторами на меньшие части с помощью применения цикла. Также может помочь очистка больших массивов в вашем рабочем пространстве. ПРИМЕР: Вы поймете это, когда вы столкнетесь с этой ошибкой! Наиболее распространенные ошибки Все наиболее распространенные ошибки были описаны ранее. Но, чтобы помочь вам предупредить эти ошибки, мы собрали их здесь в одном списке, к которому вы можете обращаться время от времени. Это поможет вам укрепить «хорошие привычки» работы со средой MATLAB: • Невыполнение очистки переменных или неприсвоение переменным начальных значений; • Неправильное использование встроенных функций; • Невнимание к порядку старшинства арифметических действий; • Неверное использование арифметических символов; • Несогласованные разделители; • Использование неправильных разделителей; • Построение графика для другого объекта; • Использование прописных букв вместо строчных в командах среды MATLAB или ошибки в написании команд. Методики отладки Теперь, когда мы рассмотрели наиболее общие ошибки, пришло время узнать, как можно отладить ваши М-файлы и как определить нахождение и исправить те противные ошибки, которые не вписываются в четкие категории, описанные выше.
Глава 11. Разрешение проблем 259 Если один из ваших М-файлов не работает так, как вы ожидали, то, вероятно, самая простая вещь, которую вы можете сделать, чтобы отладить его - это вставить команду keyboard где-нибудь в середине. Эта команда временно приостанавливает (но не прекращает) выполнение программы и позволяет вводить команды с клавиатуры, когда вы получите специальное приглашение с символом К. В это время вы можете выполнить любые команды, которые захотите (например, исследовать некоторые из переменных). Чтобы вернуться к выполнению М-файла, наберите команду return или dbcont для продолжения отладки. Более методичный способ отлаживать М-файлы состоит в том, чтобы использовать средства отладки редактора/отладчика М-файлов среды MATLAB. Начните с выбора элемента меню Tools ¦ Check Code with M-Lint (Инструменты ¦ Проверка кода на М-стандарт). Эта команда проверяет код М-файла на присутствие общих и синтаксических ошибок и выводит сообщение, указывающее, где располагаются возможные ошибки. (Вы можете сделать то же самое из командного окна с помощью команды mlint, после которой необходимо через пробел указать название проверяемого файла.) Затем используйте отладчик, чтобы вставить в файл «проверочные точки». Обычно, чтобы их вставить, используется меню Debug ¦ Set/clear breakpoint (Отладка ¦ Установить/снять проверочную точку) или значок Set/clear breakpoint (Установить/снять проверочную точку) в панели инструментов окна Editor (Редактор), но вы можете также сделать это из командного окна с помощью команды dbstop. (Смотрите описание указанной команды в оперативной справке.) Как только проверочная точка вставлена в М-файл, вы будете видеть небольшую красную точку рядом с со строкой в редакторе/отладчике. (Как показано в примере (Рис. 11.3), расположенном ниже.) Затем, когда вы вызовете М-файл, выполнение остановится в проверочной точке и, также, как в случае с командой keyboard, управление вернется в командное окно, где вы увидите особенное приглашение с символом К. Напомним, что когда вы будете готовы возобновить выполнение М-файла, наберите dbcont. Когда вы закончите выполнение отладки, используйте команду dbclear, чтобы «снять» проверочные точки в М-файле. Давайте посмотрим применение этих методик на примере. Предположим, что вы хотите создать М-файл для функции, который получает в качестве входных параметров два выражения f и g (заданные или как символьные выражения, или как строки) и два числа а и Ь. Затем этот М-файл строит функции ? и g на промежутке между х = аих = Ъи закрашивает область между ними. Для первой попытки вы могли бы начать с М-файла shadecurves.m, состоящего из девяти строк, который выглядит следующим образом: function shadecurves(?, g, a, b) 5&SHADECURVES Рисует область между двумя кривыми % SHADECURVES (?, д, а, Ь) получает строки или выражения ? % и д, воспринимает их как функции, строит их на промежутке % между х=аих=Ьи закрашивает область между ними.
260 MATLAB % Пример: shadecurves ('sin (x)¦# '-sin (x) ', 0, pi) ffun = inline(vectorize(?)); gfun = inline(vectorize(g)); xvals = a:(b - a)/50:b; plot([xvals/ xvals], [ffun(xvals)# gfun(xvals)]) Давайте выполнять М-файл с данными, установленными в пояснениях к этой функции: 10 0.5 1 1.5 2 2.5 3 3.5 Рис. 11.3. Первая попытка закрашивания области между sin х и-sin у График, показанный на Рис. 11.3, был получен с помощью выполнения следующей команды >> shadecurves('sin(x)¦, '-sin(xI, 0, pi) или >> syms x; shadecurves(sin(x), -sin(x), 0, pi) Это не совсем то, что мы хотели получить. График, который нам нужен, показан на следующем Рис. 11.4. 0 0.5 1 1.5 2 2.5 3 3.5 Рис. 11 Л. Закрашенная область между sin x и-sin x
Глава 11. Разрешение проблем 261 Чтобы начать определять, что вышло не так, как надо, давайте попробуем другой пример, скажем >> syms х; shadecurves(xA2# sqrt(x), 0, 1); axis square Теперь мы можем увидеть результат (Рис. 11.5). 02 04 06 08 1 Рис. 11.5. Первая попытка закрасишь облаешь между jc2 и Vx Легко выяснить, почему наши области получились незакрашенными. Это произошло потому, что мы использовали команду plot (которая строит кривые) вместо команды patch (которая строит заполненные области). Таким образом, можно предложить, чтобы мы попробовали изменить последнюю строку М-файла на следующую команду: patch([xvals, xvals], [ffun(xvals), gfun(xvals)]) Эта команда приводит к появлению сообщения об ошибке: ??? Error using ==> patch Not enough input arguments. Error in ==> shadecurves at 9 patch([xvals, xvals], [ffun(xvals), gfun(xvals)]) поэтому мы обращаемся к справке и пробуем набрать >> help patch чтобы увидеть, используем ли мы синтаксис правильно. Строки подсказки указывают, что команды patch требует третьего параметра, цвета (в координатах формата RGB), которым необходимо заполнить нашу область. Таким образом, мы получаем следующую строку: patch([xvals, xvals], [ffun(xvals), gfun(xvals)], [.5,0,.7]) Теперь мы можем получить новый результат (Рис. 11.6) >> syms x; shadecurves(хА2, sqrt(x), 0, 1); axis square
262 MATLAB Результат выглядит лучше, но он все еще не совсем верен, поскольку мы можем видеть таинственную диагональную линию ниже середины рисунка. Но если мы пробуем >> syms x; shadecurves(xA2, хЛ4, -1.5, 1.5) то мы получим довольно причудливый рисунок (Рис. 11.7). Поскольку в нашем М-файле нет большого числа строк, а строки 7 и 8 не вызывают сомнений, то ошибка должна быть связана с последней строкой. Мы должны перечитать оперативную справку для команды patch. В ней говорится, что команда patch рисует заполненный двухмерный многоугольник, определенный векторами X и Y, которые являются первыми двумя входными параметрами команды. Чтобы увидеть, как выполняется эта команда, необходимо изменить «50» в строке 9 в нашем М-файле на что-нибудь значительно меньшее, скажем, на 5, и затем вставить проверочную точку в М-файл перед строкой 9. Рис. 11.6. Вторая попытка заполнения области между х2 и Рис. 11.7. Первая попытка закрасить область между х2 и х4 Теперь М-файл в окне Editor (Редактор) похож на окно, изображенное на Рис. 11.8. Обратите внимание на то, что большая точка слева от последней строки обозначает проверочную точку. Когда мы выполняем М-файл с теми же самыми вход-
Глава 11. Разрешение проблем 263 ными параметрами, мы теперь получаем в командном окне приглашение К>>. В этот момент разумно пробовать перечислить координаты точек, которые являются вершинами нашего заполненного многоугольника, таким образом, мы пробуем К>> [[xvals, xvals]1, [ffun(xvals), gfun(xvals)]¦] ans = -1.5000 2.2500 -0.9000 0.8100 -0.3000 0.0900 0.3000 0.0900 0.9000 0.8100 1.5000 2.2500 -1.5000 5.0625 -0.9000 0.6561 -0.3000 0.0081 0.3000 0.0081 0.9000 0.6561 1.5000 5.0625 -Э г и - 1 .0 hi .| ** %*¦;¦ function shadecurves(?, g, a, b) 4SHADECURVES Строит область между двукя кривыми Ч SHADECURVES (?, д, а, Ь) получает строки или выражения ? Ч и д, воспринимает их как функции, строит эти функции между *хваих«Ьи закрашивает область между ними. к Пример: shadecurves ('sin (x)', '-sin (x) ', 0, pi) ffun - inline(vectorize(?)); glun - inline(vectorize(g)); xvals - a:(b - a)/50:b; slavx « b:(a - b)/S0:a; patchttxvals, slavx], [«un(xvals) , ofun (slavx) ], [.5,0,.7])| shadecurves*; Го! 61 :-;-i0VR ,. Puc. 11.8. Редактор/отладчик Если мы теперь наберем К» dbcont то мы увидим в графическом окне несколько измененную фигуру (Рис. 11.9).
264 MATLAB -1.5 -1 -0.5 0 0.5 1 1.5 Рис. 11.9. Вторая попытка закрашивания области между х2 их4 Наконец, мы можем понять, что происходит: среда MATLAB соединила точки, координаты которых были только что напечатаны. В частности, среда MATLAB провела линию от точки A,5; 2,25) к точке (-1,5; 5,0625). Получилось не так, как нам необходимо. Мы хотели, чтобы среда MATLAB соединила точку A,5; 2,25) на кривой у = х2 с точкой A,5; 5,0625) на кривой у = х4. Мы можем исправить эту ошибку с помощью изменения порядка координат х, в которых мы вычисляем вторую функцию д. Так, с помощью присвоения переменной slavx значений xvals, записанных в обратном порядке, мы исправили М-файл, чтобы он выглядел следующим образом: function shadecurves(?, g, a, b) ^SHADECURVES Строит область между двумя кривыми % SHADECURVES (?, g, a, b) получает строки или выражения ? % и д, воспринимает их как функции, строит эти функции между %х=аих=Ьи закрашивает область между ними. % Пример: shadecurves ('sin (x)¦, '-sin (x) ', 0, pi) ffun = inline(vectorize(f)); gfun = inline(vectorize(g)); xvals = a:(b - a)/50:b; slavx = b:(a - b)/50:a; patch([xvals, slavx], [ffun(xvals), gfun(slavx)], [.5,0,.7]) Теперь все работает должным образом. Образец результата из этого М-файла был показан ранее (Рис. 11.4). Испытайте эту программу на других примерах, которые мы рассмотрим, или на примерах по вашему выбору.
Ответы к практическим занятиям Ответы к практическому занятию А: алгебра и арифметика 1. (а) » 1111 - 345 ans = 766 (б) >> format long; [expA4)# 382801*pi] ans = 1.0е+06 * 1.20260428416478 1.20260480938683 Второе число больше. (в) » [2709/1024; 10583/4000; 2024/765] ans = 2.64550781250000 2.64575000000000 2.64575163398693 » sqrtG) ans = 2.64575131106459 Третье число, равное 2024/765, является наилучшим приближением. 2. (а) >> cosh@.1) ans = 1.00500416805580
266 MATLAB (б) » logB) ans = 0.69314718055995 (в) » atan(l/2) ans = 0.46364760900081 >> format short 3. >> [x# y, z] ¦ solve('3*x + 4*y + 5*z = 21,... •2*x - 3*y + 7*z - -I1, 'x - 6*y + z a 3',... •X', 'y'# '2') X = 241/92 У = -21/92 z = -91/92 Теперь мы проверим ответ. » А = [3, 4, 5; 2, -3, 7; 1, -6, 1]; А* [х; у; z] ans = 2 -1 3 Все получается правильно! 4. » [х# у, z] в solve('3*х - 9*у + 8*z - 2'# ... •2*х - 3*у + 7*z = -1"# 'х - б*у + z = 3'# ... •х'# 'у', 'z') X = 22/5+39/5*у
Ответы к практическим занятиям 267 У = У z = -9/5*у-7/5 Мы получаем семейство ответов с одним параметром в зависимости от переменной у. На самом деле три плоскости, определенные этими тремя линейными уравнениями, не являются независимыми, потому что первое уравнение является суммой второго и третьего. Положение точек, которые удовлетворяют этим трем уравнениям - это не точка, не пересечение трех независимых плоскостей, а скорее линия, пересечение двух различных плоскостей. Проверим еще раз. » В = [3, -9, 8; 2, -3, 7; 1, -6, 1]; В*[х; у; z] ans = 2 -1 3 5. >> syxns х у; factor(xA4 - уА4) ans = (х - у)*(х + у)*(хЛ2 + УЛ2) 6. (а) simplifyA/A + 1/A + 1/х))) ans = (б) » simplify(cos(x)A2 - sin(x)A2) ans = 2*cos(x)/42-l Давайте теперь попробуем использовать команду simple. » [better how] = simple (cos (x) A2 - sin(x)A2) better = cosB*x)
268 MATLAB how = combine (trig) 7. » 3A301 pretty(syxn(l3l)A301) ans = 4.1067e+143 410674437175765127973978082146264947899391086876012309414440570 2351069915X3249722978140061846706682416475145332179398212844053 819829708732369X8003 » 410674437175765127973978082146264947899391086876012309414440 5702351069915X3249722978140061846706682416475145332179398212844 053819829708732369X8003 ans = 1.0114e+010 Но отметьте следующее: » sym('3A301I ) ans = Это не работает, потому что команда sym сама по себе не выполняет вычисления. 8. (а) >> solve(f67*x + 32 = О1, 'х') ans = -32/67 (б) >> vpa(ans, 15) ans = -.477611940298507 (в) » pretty(solve('хА3 + р*х + q в О1, 'х')) [ 1/3 р ] [ 1/6 %1 - 2 ] [ 1/3 ]
Ответы к практическим занятиям 269 %1 [ 1/3 р 1/2 / [- 1/12 %1 + + 1/2 13 | 1/6 [ 1/3 | [ %1 \ 1/3 р \] +2 |] 1/3 |] [ 1/3 р 1/2 / 1/3 р \] [- 1/12 %1 + 1/2 I 3 11/6 %1 +2 |] [ 1/3 | 1/3 |] [ %1 \ %1 /] 3 2 1/2 %1 := -108 q + 12 A2 р + 81 q ) Обратите внимание, как команда pretty выделяет подвыражение которое встречается в формулах для всех трех корней, и как эта команда присвоила этому выражению название. Данное выражение тесно связано с дискриминантом кубического уравнения. (г) >> ezplot('ехр(х)¦); hold on; ezplot('8*x - 41) title(«eAx and 8x - 4•) ex and 8x - 4 -60 -6 -4
270 >> ?zero('exp(x) - 8*x + 41, 1) ans = 0.7700 » fzero('exp(x) - 8*x + 41, 3) ans = 2.9929 9. (a) » hold off; ezplot('xA3 - x1, [-4 4]) X3-X MATLAB F) ezplot( lsin(l/x/42) ' , [-2 2]) sinA/x2) -0.5 -1 -2
Ответы к практическим занятиям 271 » X ш -2:0.1:2; plot(X# sin(l./X. Л2)) Warning: Divide by zero. -0.5 Оба рисунка неполны. Давайте посмотрим, что получается, если мы уточним сетку. >> X = -2:0.001:2; plot(X, sin(l./X.А2)) Warning: Divide by zero. -0.5 -2 -1 Этот рисунок выглядит лучше, но из-за чрезвычайно сильного колебания рядом с х = 0 ни функция plot, ни команда ezplot не позволяет получить полностью точный график функции. (в) » ezplot (• tan (х/2)', [-pi pi]); axis([-pi# pi/ -10/ 10])
272 MATLAB tan(x/2) (r) » X = -1.5:0.01:1.5; » plot(X# exp(-X.A2)# X, 2.5 2 1.5 1 0.5 0 -0.5 - X.A2) / / / _o.5 0.5 1.5 10. Давайте построим функции 2х и х4 и найдем точки пересечения. Мы построим их сначала с помощью функции ezplot, только чтобы получить представление о графике. >> ezplot('хА4'); hold on; ezplot('2Ах"); hold off title(fxA4 and 2Ax«)
Ответы к практическим занятиям 273 х4 and 2х Обратите внимание на большой вертикальный диапазон. Мы видим из графика, что нет никаких точек пересечения между значениями 2 и 6 или между -6 и -2, но есть, очевидно, две точки пересечения между -2 и 2. Давайте теперь воспользуемся функцией plot и сосредоточимся на промежутке между -2 и 2. Мы покажем функцию х4 пунктирной линией. » X = -2:0.1:2; plot(X# 2.AX); >> hold on; plot(X# X.A4# '--•); hold off 16 14 12 10 8 6 4 2 -2-1012 Мы видим, что есть точки пересечения около -0.9 и 1.2. Существуют ли какие- либо другие точки пересечения? Налево от 0 функция 2х всегда меньше 1, тогда как функция х4 уходит к бесконечности, поскольку х уходит к отрицательной бесконечности. На другой стороне и х4, и 2х стремятся к бесконечности, поскольку х уходит в бесконечность, таким образом, графики могут пересечься снова где-то справа после значения 6. Давайте проверим. » X = 6:0.1:20; plot(X, 2.AX); » hold on; plot(X, X.A4, •--¦); hold off \ \ \ \ \ t t \ у \ \ \ \ \ \ \ \ N N \ \ \ / / / / / _, r / / 1 - 1 1 1 - / / / / /
274 MATLAB Мы видим, что они действительно пересекаются снова рядом с х = 16. С помощью некоторых вычислительных методов вы можете показать, что графики больше никогда не пересекутся (например, с помощью взятия логарифмов), таким образом, мы нашли все точки пересечения. Теперь давайте использовать команду fzero, чтобы найти значения этих точек численно. Эта команда ищет решение около заданной начальной точки. Чтобы найти три различные точки пересечения, мы должны будем использовать три различных начальных точки. Вышеупомянутый графический анализ предлагает эти отправные точки. >> rl = fzero('2Ax - хА4", -0.9) r2 = fzero(Ax - xA4', 1.2) гЗ в fzeroC2Ax - хА4'# 16) rl = -0.8613 г2 = 1.2396 гЗ = 16 Давайте проверим, удовлетворяют эти «решения» нашему уравнению. >> subs('2Ax - хА4«, 'х1, rl) subs('2Ax - хА4', 'х1, г2) subs('2Ax - xA4f, 'x1, r3) ans = 1.1102е-016 ans =
Ответы к практическим занятиям 275 -8.8818е-016 ans = О Таким образом, rl и г2 удовлетворяют уравнению приблизительно, а гЗ удовлетворяет уравнению точно. Очевидно, что 16 является решением. Также интересно пробовать использовать команду solve для этого уравнения. >> symroots a solve('2Лх - хА4 = О1) symroots = -4*lambertw(-l/4*logB))/logB) -4*lambertw(-l/-l/4*logB))/logB) -4*lambertw(-l/4*i*logB))/logB) -4*lamhertv/(l/4*logB))/logB) -4*lambertw(l/4*i*logB))/logB) Функция lambertw является «специальной функцией», которая встроена в среду MATLAB. Вы сможете узнать о ней больше, если наберете команду help lambertw. Давайте посмотрим на полученные значения решений. >> double (symroots) ans = 1.2396 16.0000 -0.1609 + 0.959И -0.8613 -0.1609 + 0.959H На самом деле мы получаем три действительных и два комплексных решения. Наши действительные решения соответствуют точкам пересечения графиков. Ответы к практическому занятию В: исчисления, графика и линейная алгебра 1. (а) » [Х# Y] =meshgrid(-l:0.1:l, -1:0.1:1); contour(X, Y, 3*Y + Y.*3 - Х.Л3, 'к')
276 MATLAB 0.5 -0.5 -1 -1 -0.5 0 0.5 1 » [X, Y] = meshgrid(-10:0.1:10, -10:0.1:10); contour(X, Y, 3*Y + Y.A3 - X.A3, 'k') 10 -5 ( ) / Су ) 1-°10 -5 0 5 10 Ниже показан график с большим числом линий уровня. » [X, Y] a meshgrid(-10:0.1:10# -10:0.1:10); contour(X# Y# 3*Y + Y.A3 - X.A3, 30# "k")
Ответы к практическим занятиям 277 (б) Теперь мы построим линию уровня через 5. » [X, У] =meshgrid(-5:0.1:5, -5:0.1:5); contour(X# Y, 3.*Y + У.А3 - X.A3, [5 5]/ 'к1) (в) Мы обращаем внимание, что f A# 1) = 0,и таким образом, команды, необходимые для построения линии уровня через точку A; 1), выглядят следующим образом: » [Х# Y] =meshgrid@:0.1:2, 0:0.1:2); contour(X, Y# Y.*log(X) + X.*log(Y), [0 0] , 'k') Warning: Log of zero. Warning : Log of zero. 2r
278 MATLAB 2. Мы находим производные данной функции: >> syms х г (а) » diffF*xA3 - 5*хА2 + 2*х - 3, х) ans = 18*х/ч2-10*х+2 (б) » diff(B*x - 1)/(хл2 + 1), х) ans = 2/(хА2+1)-2*B*х-1)/(хл2+1)Л2*х >> simplify(ans) ans = -2*(хл2-1-х)/(хл2+1)л2 (в) » diff(sinC*xA2 + 2), х) ans = 6*со8C*хл2+2)*х (г) » diff(asinB*x + 3), х) ans = 1/ (-2-х/ч2-3*х)/чA/2) (Д) » diff(sqrt(l + х*4),х) ans =
Ответы к практическим занятиям 279 (е) » diff(хАг, х) ans = (ж) » diff(atan(xA2 + 1), х) ans = 2*x/(l+(xA2+l)/s2) 3. Мы вычисляем следующие интегралы. (а) » int(cos(x), x# О, pi/2) ans = 1 (б) » int(x*sin(xA2), x) ans f -l/2*cos(xA2) Чтобы проверить неопределенный интеграл, мы просто дифференцируем. » diff(-cos(x*2)/2, x) ans = x*sin(x/42) (в) » int(sinC*x)*sqrt(l - cosC*x))# x) ans = 2/9* (l-cosC*x)) Л C/2)
280 MATLAB >> di??(ans, x) ans = sinC*x)*(l-cosC*x))л A/2) (г) » int(xA2*sqrt(x + 4)# x) ans = 2/7*(x + 4)лG/2) - 16/5*(x + 4)лE/2) + 32/3*(x + 4)лC/2) >> di??(ans, x) ans = (x + 4)*E/2) - 8*(x + 4)лC/2) + 16*(x+4)лA/2) >> simplify(ans) ans = х/ч2*(х+4)/ч A/2) (Д) » int(exp(-xA2), x, -Inf# Inf) ans = pi^ A/2) 4. (a) >> syms x; int(exp(sin(x)), x, 0, pi) Waning: Explicit integral could not be found. > In sym.int at 58 ans = int(exp(sin(x)),x = 0 .. pi) >> format long; quadl(@(x) exp(sin(x))/ 0, pi)
Ответы к практическим занятиям 281 ans = 6.20875803571375 (б) » quadl (@(x) sqrt(x.A3 + 1), О, 1) ans = 1.11144798484585 (в) С помощью среды MATLAB мы получили точное значение интеграла для этого примера в пункте 3(е). Давайте проинтегрируем его численно и сравним ответы. К сожалению, диапазон бесконечен, поэтому, чтобы использовать команду quadl, мы должны сапроксимировать промежуток. Обратите внимание на то, что результат » ехр(-35) ans = 6.305116760146989е-16 близок к обычной точности для чисел с плавающей запятой, таким образом >> format long; quadl(@(х) exp(-x.A2), -35, 35) ans = 1.77245385102263 >> sqrt(pi) ans = 1.77245385090552 Ответы сходятся, по крайней мере, до восьмого знака. 5. (а) » limit (sin(х)/х, х# 0) ans = 1 F) l + cos(x))/(x + pi)# x# -pi)
282 MATLAB ans = 0 (в) » limit(xA2*exp(-x), x, Inf) ans = 0 (r) » limit(l/(x - 1)# x# 1, 'left') ans = -Inf (Д) » limit(sinA/x), x, 0, 'right1) ans = -1 . . 1 Это означает, что каждое действительное число в промежутке между -1 и +1 является «предельной точкой» функции sin(l/x), поскольку х стремится к нулю. Вы можете увидеть почему, если построите функию sin A/х) на промежутке @,1). » ezplot(sin(l/x), [0 1]) sinA/x) 0.2 0.4 0.6 0.8 1 -0.5
Ответы к практическим занятиям 283 6. (а) >> syms k n г х z >> symsum(kA2, к, 0, п) ans = 1/3*(п+1)лЗ-1/2*(п+1)А2+1/6*п+1/6 >> simplify (axis) ans = l/3*nA3+l/2*nA2+l/6*n (б) >> syxnsuxn(rAk, к, 0, п) ans = >> pretty(ans) (n + 1) r r - 1 r - 1 (в) » symsuxn(xAk/?actorial(k), k, 0, Inf) Error using ==> factorial N must be a matrix of non-negative integers. Ниже показаны два пути выхода из этого затруднения. >> symsum(xAk/gainma(k + 1), k# 0, Inf) ans = exp (x) » symsum(xAk/sym('к! •)/ к, 0, Inf)
284 MATLAB ans = exp(x) (r) » symsum(l/(z - k)A2, k, -Inf, Inf) ans = pi^2 + pi2*cot(pi*z)/42 7. (a) >> taylor(exp(x), 7, 0) ans = 1+х+1/2*х/ч2+1/6*х/ >> taylor(sin(x), 5, 0) ans = x-l/6*x/43 F) » taylor(sin(x)# 6, 0) ans = х-1/6*х/чЗ+1/120*хл5 (в) >> pretty(taylor(sin(x), 6, 2)) 2 3 sinB) + cosB)(x - 2) - l/2sinB)(x - 2) - l/6cosB)(x - 2) 4 5 + 1/24 sinB) (x - 2) + 1/120 cosB) (x - 2) (r) » taylor(tan(x), 7, 0)
Ответы к практическим занятиям 285 ans = х+1/3*х/чЗ+2/15*х/ч5 (д) » taylor(log(x), 5, 1) ans = х-1-1/2*(х-1)л2+1/3*(х-1)*3-1/4*(х-1) (е) » pretty(taylor(erf(х), 9, 0)) 3 5 7 XXX X 2 2/3 + 1/5 1/21 1/2 1/2 1/2 1/2 pi pi pi pi 8. (a) >> syms x y; ezsurf(sin(x)*sin(y), [-3*pi 3*pi -3*pi 3*pi]) sin(x) sin(y) -5 F) » syms x y; ezsurf((хл2 + yA2)*cos(xA2 + yA2)# [-1 1-11])
286 0.5* MATLAB -0.5- -1 1 -1 -1 -0.5 9. >> T = 0:0.01:1; >> for j = 0:16 fillD*cos(j*pi/8) + (l/2)*cosB*pi*T) 4*sin(j*pi/8)+(l/2)*sinB*pi*T)/ 'r1) axis equal; axis([-5 5 -5 5]); M(j+1) = getframe; end >> movie (M) -5 Конечно, мы не можем показать целый фильм в этой книге, но на рисунке выше вы можете увидеть последний кадр из фильма.
Ответы к практическим занятиям 287 10. (а) » А1 = [3 4 5; 2 -3 7; 1 -б 1]; b = [2; -1; 3]; >> format short; x = Al\b х = 2.6196 -0.2283 -0.9891 А1*х ans = 2.0000 -1.0000 3.0000 (б) » А2 а [3 -9 8; 2 -3 7; 1 -б 1]; b = [2; -1; 3]; » х = A2\b Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 7.680447e-018. x = -1.2731 -0.7273 -0.0908 >> A2*x ans = 2 -1 3 Матрица А2 яляется вырожденной. Действительно, » det(A2)
288 MATLAB ans = 0 (в) » A3 о [l 3 -2 4; -2 3 4 -1; -4 -3 1 2; 2 3 -4 1] ; » ЬЗ = [1; 1; 1; 1] ; х = АЗ\ЬЗ X = -0.5714 0.3333 -0.2857 0.0000 » А3*х ans = 1.0000 1.0000 1.0000 1.0000 (г) >> syms abcdxyuv; » А4 = [a b; с d] ; А4\ [u; v] ans = (d*u-b*v)/(d*a-b*c) -(c*u-v*a)/(d*a-b*c) » det(A4) ans = d*a-b*c
Ответы к практическим занятиям 289 Определитель матрицы коэффициентов является знаменателем в ответе. Таким образом, ответ можно получить, только если матрица коэффициентов невырождена. 11. (а) » rank(Al) ans = 3 » rank(A2) ans = 2 » rank(A3) ans = 4 » rank(A4) ans = 2 Среда MATLAB неявно предполагает, что ad - be здесь не равно 0. (б) Только второй вычисленный элемент является вырожденным. (в) » det(Al) ans = 92 » inv(Al) ans = 10-1605
290 MATLAB 0.4239-0.3696 0.4674 0.0543-0.0217 -0.1196 -0.0978 0.2391 -0.1848 det(A2) ans = У матрицы А2 нет обратной матрицы. » det(A3) ans = 294 » inv(A3) ans = 0.1837 0 0.1633 0.2857 » det(A4) ans = d*a - b*c » inv(A4) ans = [ d/(d*a-b [ -c/(d*a-b 12. (a) » [Ul, Rl] -0. 0. 0. -0. *c), *c), 1531 1667 0306 0714 -b/(d* a/(d* = eig(Al) -0. -0. a-b a-b 2857 0 1429 0 *c)] *c)] -0 0 -0 -0 .3163 .1667 .3367 .2143
Ответы к практическим занятиям 291 U1 -0 -0 0 R1 3. = .9749 .2003 .0977 = 3206 0 0 0 0 -0 0 -1.1603 0 .6036 .0624 .5522 + 5. + 0.540П + 0.1877i 1342i -1. - 0 0 .1603 0.6036 0.0624 - 0.5401i -0,5522 - 0.1877i » A1MJ1 - U1*R1 ans = 1.0e-014 * 0.3109 -0.0333 -0.0833 0.2554 - 0.3553i 0.2554 + 0.3553i -0.1776 - 0.3220i -0.1776 + 0.3220i -0.1721 - 0.0444i -0.1721 + 0.0444i Это по существу нуль. Обратите внимание на е-14. » [U2, R2] = eig(A2) U2 0. 0. -0 R2 -0 >> = 9669 1240 .2231 = .0000 0 0 A2*U2 0.7405 0.4574 0.2831 0 0.5000 0 - U2*R2 - 0. + 0. + 6. 2848i 2848i 5333i 0.7405 0.4574 0.2831 0 0 0.5000 - + 0.2848i - 0.2848i 6.5383i ans =
292 MATLAE 1.0e-014 * -0.3154 -0.3331 - 0.444H -0.3331 + 0.444H -0.2423 0.0888 + 0.3109i 0.0888 - 0.3109i -0.1140 -0.0222 + 0.2665i -0.0222 - 0.2665i Здесь можно привести тот же самый комментарий, что и в пункте (а). » [U3, R3] = eig(A3); » max(abs(A3*U3 - U3*R3)) ans = 1.0e-014 * 0.2648 0.2648 0.2610 0.2610 Опять получены маленькие значения. (Обратите внимание, что мы отменили вывод результата первой команды и взяли наибольшее значение по модулю элементов в каждом столбце A3*U3 - U3*R3, чтобы данные не занимали много места на экране.) » [U4, R4] = eig(A4); » pretty (U4) [ 2 2 1/2 [ 1/2 d - 1/2 а - 1/2 (d - 2 d a + а + 4 b с) [ f [ с 2 2 1/2] 1/2 d - 1/2 а + 1/2 (d - 2 d a + а + 4 b с) ] ] с ] [1 , 1] pretty(R4) [ 2 2 1/2] [1/2 d + 1/2 а + 1/2 (d - 2 d a + а + 4 b с) ,0]
Ответы к практическим занятиям 293 [ 2 2 1/2] [О , 1/2 d + 1/2а - 1/2 (d - 2 d a + а + 4 b с) ] » simplify(A4*U4 - U4*R4) ans = [ 0, 0] [ 0, 0] (б) » А = [10 2; -10 4; -1-15] ; >> [Ul, Rl] = eig(A) U1 -0 -0 -0 Rl 2. >> >> U2 R2 2. = .8165 .4082 .4082 = 0000 0 0 В = [5 2 [U2, R2] 0.8165 0.4082 0.4082 = 0000 0.5774 0.5774 0.5774 0 3.0000 0 -8; 3 б = eig(B) -0.5774 -0.5774 -0.5774 0 0 -1.0000 0 0 3. 0.7071 -0.7071 0.0000 0 0 1.0000 -10; 3 3 -7]; 0.7071 -0.7071 0.0000 0 0 0000 Можно заметить, что первые и вторые столбцы матрицы U1 равны по значениям, но противоположны по знакам соответствующим величинам столбцов U2, а третьи столбцы в обеих матрицах одинаковы. Итак,
294 MATLAB А*В - В*А ans = 13. (а) 00 00 00 0 0 0 Если мы принимаем, что Хп является матрицей-столбцом с элементами Хп, уа и zn, а М - квадратной матрицей с элементами 1, 1/4, 0; 0, 1/2, 0; 0, j, 1 тогда Ха+1 = (б) Мы получаем Хп (в) » М = [1, 1/4, 0; 0, 1/2, 0; 0, 1/4, 1]; » [U,R] - eig(M) и = 1.0000 0 0 R = 1.0000 0 0 (г) 0 0 1.0000 0 1.0000 0 -0.4082 0.8165 -0.4082 0 0 0.5000 Переменная М должна быть URU. Давайте проверим: » М - U* R*inv(U) ans = 0 0 0 0 0 0
Ответы к практическим занятиям 295 0 0 0 Так как Rn является диагональной матрицей с элементами 1,1, 1/2п, мы знаем, что Roo является диагональной матрицей с элементами 1,1,0. Поэтому М» = XJRJJ" 1. Таким образом, » Minf = U*diag([l# 1, 0])*inv(U) Minf = 1.0000 0.5000 0 0 0 0 0 0.5000 1.0000 (д) >> syms хО уО z0; Х0 = [хО; уО; z0]; Minf*X0 ans = хО+1/2*уО 0 l/2*yO+zO Половина смешанного генотипа переходит к доминирующему генотипу, а другая половина смешанного генотипа переходит к рецессивному генотипу. Они добавляются к исходным чистым видам, соотношения которых сохраняются без изменений. (е) » МА5*Х0 ans = хО+31/64*уО 1/32*уО 31/64*yO+zO » МА10*Х0 ans = хО+1О23/2О48*уО 1/1О24*уО
296 MATLAE 1023/2048*y0+z0 (ж) С предложенной дополнительной моделью подходят только первые три столбце таблицы, матрица перехода М становится равной М = [1 1/2 0; 0 1/2 1; С 0 0 ]. Вы можете вычислить, что возможные распределения численности вид< равны [1 0 0 ] и они независят от начальной численности. 14. Следующие команды создают файл JPEG с изображением французского флага Команда set не оказывает никакого влияния на файл JPEG. Мы использовали эт; команду, только чтобы оключить отметки на осях в графическом окне. » А = zerosB00# 300, 3); » А(:, 1:100, 3) = onesB00, 100); » А(:, 101:200, 1) = onesB00, 100); » А(:, 101:200, 2) = onesB00, 100); » А(:, 101:200, 3) = onesB00, 100); » А(:, 201:300, 1) = onesB00, 100); >> image(A); axis equal tight » set(gca, «XTick1, []), set(gca, 'YTick1, []) » imwrite(A, ¦tricolore•jpg¦) Теперь мы переопределяем цвет крайней левой трети массива и создаем фай; JPEG с изображением итальянского флага. » А(:, 1:100, 3) = zerosB00, 100); » А(:, 1:100, 2) = onesB00, 100); >> image(A); axis equal tight » set(gca, 'XTick1, []), set(gca, ¦YTick1, []) » imwrite(A, 'italia.jpg')
Ответы к практическим занятиям 297 Конечно, вы должны будете выполнить команды, показанные выше, самостоятельно, чтобы увидеть флаги в цвете. Затем вы можете выполнить команды, перечисленные ниже, чтобы посмотреть фильм, в котором французский флаг пре- образовается в итальянский. >> clear M >> for k = 0:10 А(:# 1:100, 3) = A0-к)*onesB00, 100)/10; А(:, 1:100# 2) = k*onesB00, 100)/10; М(к+1) = im2frame(A); end >> movie (M) Ответы к практическому занятию С: развитие навыков работы с программой MATLAB >> clear all 1. (а) » radiation = @(х, у, хО, уО) 10000./D*pi*((х - хО).А2 + ... (у - уО).Л2 + 1)); » хО = 50*rand(l, 5); уО = 50*rand(l, 5); >> [X, Y] =meshgrid@:0.1:50, 0:0.1:50); » contourf(X, Y, radiation(X, Y# x0(l), y0(l)) + ... radiation(X, Y# xOB), yOB)) + ...
298 MATLAB radiation(X, Y, xOC), yOC)) + ... radiation(X, Y, xOD), yOD)) + ... radiation(X, Y, xOE), yOE)), 20) >> colormap (¦ gray') 50i Из рисунка не совсем ясно, где можно скрыться, хотя кажется, что капитан обладает довольно хорошими шансами на выживание при небольшом числе выстрелов. Но 100 выстрелов может быть достаточно, чтобы найти его. По интуиции можно порекомендовать ему оставаться близко к границе. (б) Ниже показан ряд команд, которые помещают Пикарда в центр арены, запускают смертельный луч 100 раз и затем определяют здоровье Пикарда. Эти команды используют М-файл lifeordeath.m, который вычисляет судьбу капитана после отдельного выстрела. >> type lifeordeath function r = lifeordeath(xl, yl, xO, yO) % Эта функция вычисляет число единиц радиации, % которое приходит к точке (xl, yl) , предполагая, что % смертельный луч ударяет на 1 метр выше точки (хО, уО). % Если это число превышает 50, то " записывается в % переменную "г", в противном случае "г" становится равной ". dosage = 10000/D*pi*((xl - хО)л2 + (yl - уО)А2 + 1)); if dosage > 50 г = 1; else
Ответы к практическим занятиям 299 г = 0; end Ниже приведен ряд команд, с помощью которых можно исследовать вероятности выживания капитана. >> xl = 25; yl = 25; h = 0; >> for n = 1:100 хО = 50*rand; уО = 50*rand; г = li?eordeath(xl, yl, xO, yO); h = h + r; end » if h > 0 disp('Капитан мертв!') else disp('Пикард выжил!') end Капитан мертв! На самом деле, если вы выполните эту последовательность команд несколько раз, то вы увидете, что капитан умирает намного чаще, чем выживает. (в) Теперь мы используем другой М-файл - simulation.m, - который циклически выполняет действия из части (б) 100 раз и сообщает, сколько раз Пикарду удалось выжить, получая его положение как входной параметр. >> type simulation function с = simulation(xl, yl) с = 0; for k = 1:100 h = 0; for n = 1:100 xO = 50*rand; yO = 50*rand;
300 MATLAB г = lifeordeath(xl, yl, xO, yO); h = h + r; end if h == 0 с = с + 1 ; end end Итак, давайте выполним моделирование Монте-Карло, чтобы посмотреть, каковы шансы Пикарда: » xl = 25; yl ¦ 25; >> disp([' Шансы на выживание для Пикарда равны ', ... num2str(simulation(xl, yl)/100)]) Шансы на выживание для Пикарда равны 0.13 Мы выполнили это моделирование несколько раз и получили вероятности выживания в пределах от 8% до 19%. (г) » xl = 37.5; yl = 25; >> disp(['Шансы на выживание для Пикарда равны ', ... nuxn2str(simulation(xl, yl)/100)]) Шансы на выживание для Пикарда равны 0.15 На этот раз получились значения между 10 % и 24 %. Давайте продолжать перемещать капитана к краю арены. (Д) » xl = 50; yl = 25; >> disp(['Шансы на выживание для Пикарда равны ', ... num2str(simulation(xl, yl)/100)]) Шансы на выживание для Пикарда равны 0.46 После многократного выполнения этого сценария числа находятся в промежутке между 32% и 47%. Итак, наконец, предположите, что Пикард находится в углу. >> xl = 50; yl = 50;
Ответы к практическим занятиям 301 >> disp(['Шансы на выживание для Пикарда равны ', ... nmn2str(simulation(xl, yl)/100)]) Шансы на выживание для Пикарда равны 0.63 Мы получили значения между 54% и 68%. Говорят, что храбрый человек умирает, но один раз, а трус умирает тысячей смертями. Но человек, который сказал эту фразу, вероятно, никогда не встречался с кардессианами. Долгой жизни, Пикард! 2. (а) Рассмотрим состояние счета в банке в последний день каждого месяца. В конце первого месяца счет содержит М + MxJ = М/A + J) долларов. Тогда в конце второго месяца на счете будет [МA + J)](l + J) = МA + JJ долларов. Точно так же, в конце п месяца счет будет содержать М( 1 + J)n долларов. Таким образом, наша формула будет выглядеть так (б) Теперь мы принимаем М = 0, а ежемесячно вкладываемую сумму равной S долларов. В конце первого месяца счет будет содержать S + SxJ = S(l + J) долларов. На следующий день S долларов добавляются к этой сумме и затем, в конце второго месяца счет содержит [S(l + J) + S](l + J) = S[(l + JJ + A + J) ] долларов. Точно так же в конце п месяца счет будет хранить S[(l + J)n + A + JI1 + ... + A + J)] долларов. Если просуммировать геометрический ряд, то получится сумма Т на счете после п месяцев Т = 5[(A + У)л+| - (/ +1)) /(A + J) -1)] = 5[(A + J)tt+l -1) / J -1]. (в) При объединении двух моделей получается, что на счете с начальным балансом М и ежемесячным взносом S сумма денег Т через п месяцев будет (г) Нас просят решить уравнение A + 7)я=2 со значениями J = 0 .05/12 и J = 0.1/12. » months = solve('(l + 0.05/12)An =2');
302 MATLAB >> years = double(months)/12 years = 13.8918 » months - solve('(l + 0.1/12)лп = 21); >> years = double(months)/12 years = 6.9603 Если вы удвоите процентную ставку, то вы сократите время, необходимое для достижения цели, примерно в два раза. (д) >> format bank » 1000000/((A + 0.08/12)АA2*35 + 1) - 1)/@.08/12) - 1) ans = 433.06 Вы должны вносить 433.06 $ каждый месяц. (е) >> syms n » Т = 300*((A + 0.08/12)А(п + 1) - 1)/@.08/12) - 1); >> months = solve(T - 1000000); >> years = double(months)/12 years = 39.37 Вы должны работать еще приблизительно пять лет. (ж) Для начала рассмотрим взятие всей суммы сразу. Через 20 лет сумма 65 000 $ (которая останется после уплаты налогов) принесет » optionl ш 65000*A + 0.05/12)АA2*20)
Ответы к практическим занятиям 303 optionl = 176321.62 Капитал возрастет приблизительно до 176322 $. Второй вариант принесет доходов » S = 0.8*A00000/240); » option2 - S*(((l + 0.05/12)АA2*20 + 1) - 1)/@.05/12) - 1) option2 = 137582.10 В этом случае вы накопите только 137582 $. Взятие всей выплачиваемой суммы сразу является определенно лучшей стратегией. (з) » rates = [.13# .15# -.03, .05, .10, .13, .15, -.03, .05]; >> for k = 0:4 Т = 50000; for j = 1:5 Т = T*(l + rates(к + j)); end disp( [к + 1, Т ]) end 1.00 2.00 3.00 4.00 5.00 72794.74 72794.74 72794.74 72794.74 72794.74 Все результаты являются одинаковыми. Вы получите в итоге 72795 $ независимо от того, когда вы входите в цикл, потому что произведение n1<ej<e5(l+3cates( j )) не зависит от порядка, в котором размещены его элементы. Если вы кладете 50000 $ на счет в банке, платящий 8%, то вы получите » 50000*A+0.08)Л5 ans = 73466.40
304 MATLAB Таким образом, вклад в банк лучше, чем вложения в рынок. Изменчивость рынка может причнить вам ущерб по сравнению с устойчивостью банка. Но, конечно, если предположить, что вы сможете найти банк, который заплатит 8%. Теперь давайте посмотрим, что получается при отсутствии капитала, но при наличии ежегодных вложений. Здесь анализ оказывается более тонким. Установим S = 10000. В конце первого года счет содержит S(l + Гх), тогда в конце второго года [S(l + rl) + S](l + r2), где мы записали г j для rates (j ). Так, к концу пятилетнего периода сумма на счете будет произведением S и числа у?1 уЪ2 y>3 y>4 Если вы входите в деловой цикл в другой год, то элементы периодически повторяются. Таким образом, теперь мы можем вычислить » for k = 0:4 Т = ones(l, 5); for j = 1:5 ТТ = 1; for 1 = j:5 ТТ = TT*A + rates(k +1)); end T(j) = ТТ; end disp([k + 1, 10000*sum(T)]) end 1.00 61196.47 2.00 64000.40 3.00 68357.67 4.00 61884.76 5.00 60192.11 He удивительно, что все суммы оказались меньше, чем те, которые получаются при вложении исходных 50000 $ за один раз. Но в этой модели имеет значение, когда вы входите в деловой цикл. Ясно, лучше всего начать вкадывать ваши средства во время спада и закончить на подъеме. Кстати, банковская модель в этом случае приносит доход » 10000*((A + 0.08)*6 - D/0.08 - 1)
Ответы к практическим занятиям 305 ans = 63359.29 который лучше некоторых моделей с вкладами, но не всех из них. 3. (а) Мы можем использовать выражение (rand < 0.338), чтобы вычислить, получает ли Тони попадание или нет в течение одной подачи, основываясь на случайном числе, которое выбирается из промежутка от 0 до 1. Если случайное число получилось меньше, чем 0.338, то при вычислении выражения получается 1 и Тони приписывается попадание, в противном случае получается 0, и Тони засчи- тывается промах. Мы могли бы воспроизвести один год в карьере Тони, циклически вычислив это выражение 500 раз. Более простой способ состоит в том, чтобы сразу поместить 500 случайных чисел в это выражение, просуммировать результаты и разделить полученное значение на 500, чтобы получить средний уровень в течение года. Следующая функция делает именно так. Хотя она позволяет выбирать число подач в году п в более широких пределах, мы будем использовать только 500. >> yearbattingaverage = @(n) sum(rand(n, 1) < 0.338)/п; Теперь мы выполним эту функцию. >> format short >> yearbattingaverage E00) ans = 0.3380 (б) Теперь давайте напишем М-файл для функции, которая моделирует 20-летнюю карьеру. Как и для случая с числом подач за год, мы предусмотрим карьеру с изменяющейся длительностью. >> type career function ave = career(n, k) % Этот файл функции вычисляет средний уровень для каждого % года в k-летней карьере, предполагая п подач в каждом году. % Затем он сохраняет в списке среднее число для % каждого из годов в карьере, и, наконец, вычисляет
306 MATLAB % среднее число за всю деятельность. Y = zerosA, к); for j = 1:к Y(j) = sum(rand(n, 1) < 0.338)/n; end ave = sum(Y)/k; disp (['Лучшее среднее: ', (num2str (max (Y) , 4))]) disp(['Худшее среднее: ', (num2str(min(Y), 4))]) disp (['Сред, за деятельность: ', (num2str (ave, 4 ))]) Далее мы выполняем моделирование. >> avel = careerE00, 20); Лучшее среднее: 0.39 Худшее среднее: 0.292 Сред, за деятельность: 0.3394 (в) Теперь мы выполняем моделирование еще четыре раза: >> ave2 = careerE00, 20); Лучшее среднее: 0,372 Худшее среднее: 0.294 Сред, за деятельность: 0.334 >> ave3 ss careerE00, 20); Лучшее среднее: 0.3 82 Худшее среднее: 0.306 Сред, за деятельность: 0.339 >> ave4 = careerE00, 20);
Ответы к практическим занятиям 307 Лучшее среднее: 0.3 6 Худшее среднее: 0.292 Сред, за деятельность: 0.3 314 >> ave5 = careerE00, 20); Лучшее среднее: 0.38 Худшее среднее: 0.294 Сред, за деятельность: 0.339 (г) Среднее число для пяти различных 20-летних карьер: >> (avel + ave2 + ave3 + ave4 + ave5)/5 ans = 0.3366 Неплохо. На самом деле, если бы мы выполнили моделирование 100 раз и взяли бы среднее число, то оно оказалось бы очень близко к 0.338. 4. Наше решение и его результат показаны ниже. Сначала мы устанавливаем п ра- ным 500, чтобы сохранить это значение в файле и облегчить его последующее изменение. Затем мы устанваливаем подходящие размеры для матрицы А и начинаем цикл, который последовательно определяет элементы матрицы. Наконец, мы извлекаем наибольшее значение из списка собственных значений матрицы А. >> п = 500; >> А = zeros(п); >> for k = 1:п А(к, :) = 1./(к: (к + п - 1)); end >> max (eig (A)) ans = 2.3769
308 5. MATLAB Ниже мы предлагаем вам наш вариант решения и его результаты. Сначала мы определяем вектор t со значеними от 0 до 2l, чтобы позже мы могли представить окружности параметрические в виде х = г cos t, у = г sin t. Затем мы очищаем любой предыдущий рисунок, который мог быть создан ранее, и готовимся создать рисунок за несколько шагов. Пусть радиус красной окружности будет равен 1. Тогда внутренний радиус первого черного кольца должно быть равен 2, а его внешний радиус - 3, и таким образом, внутренний радиус десятого черного кольца получится равным 20, а его внешний радиус будет равен 21. Мы начинаем рисовать от внешней стороны внутрь, потому что мы планируем заполнить наибольшую окружность черным цветом, затем заполнить следующую наибольшую окружность белым цветом, оставляя только черное кольцо, затем заполнять следующую наибольшую окружность опять черным цветом, оставляя белое кольцо, и т.д. Условный оператор if выдает истину, когда значение переменной г нечетно, и ложь, когда оно четно. Мы останавливаем чередование черного и белого цветов при радиусе, равном 1, чтобы сделать последнюю окружность красной, а не черной. Затем мы настраиваем оси, чтобы окружности выглядели круглыми. >> t = linspace@, 2*pi, 100); >> cla reset; hold on » for r = 21:-1:2 if xnod(r,2) fill(r*cos(t), r*sin(t), 'k') else fill(r*cos(t)# r*sin(t), -W) end end » fill(cos(t)# sin(t), 'r1) >> axis equal; hold off -20 -10 10 20
Ответы к практическим занятиям 309 6. Ниже показано содержание М-файла с нашим решением. type mylcm function m = mylcm(varargin) nums = [varargin{:}]; if -isnumeric(nums) | any(nums ~= round (real (nums) )) | ... any(nums <= 0) error('Arguments must be positive integers.1) end for k = 2:length(nums); nums(k) = lcm(nums(k), nums(k-l)); end m = nums (end) ; Вот некоторые из примеров. Сначала случаи, в которых эта программа должна правильно выполняться: » mylcm([4 5 6]) ans = 60 » mylcm( [6 7 12 15] ) ans = 420 Далее случаи, в которых мы ожидаем появление ошибок: >> mylcmD.5, 6) Error using ==> mylcm
310 MATLAB Arguments must be positive integers. » mylcmCa1, 'b', 'с') Error using ==> mylcm Arguments must be positive integers. • 7. Далее представлено содержание М-файла с нашим вариантом решения. >> type letcount function letcount(file) if isunix [stat, str] =unix(['cat ¦ file]); else [stat, str] = dos(['type ' file]); end letters = 'abcdefghijklmnopqrstuvwxyz' ; caps = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ1 ; for n = 1:26 count(n)= sumfstr = = letters(n)) + sum(str == caps(n)) end bar(count) ylabel 'Число возникновений1 title( ['Список частот в файле ' file]) set(gca, 'XLim', [0 27] , 'XTick', 1:26, 'XTickLabel', ... letters') После выполнения этого М-файла мы получили следующий результат. >> letcount('letcount.m1)
Ответы к практическим занятиям 311 Список частот в файле letcount.m abcdefgh i j klmnopqrstuvwxyz 8. Мы обозначим через w, x, у и z число домов, посещенных в городах Готем, Мет- рополис, Оз и Ривер Сити соответственно. Тогда линейные неравенства, определенные заданными условиями, будут следующими: • Неотрицательные данные: w >0,x>0,y>0,z>0; • Брошюры: w + х + у + z й 50000; • Стоимость поездок: 0. 5w + 0.5х + у + 2z < 40000; • Доступное время: 2w + Зх + у + 4z ^ 18000; • Предпочтения: w ^ x, x + y^z; • Вклады: w + 0.25х + 0.5у + 3z t 10000. Величина, которую необходимо увеличить, следующая: • Поддержка избирателей: 0 • 6w + О.бх + 0.5у + 0.3z. (а) Эти условия позволяют нам подготовить и решить эту задачу линейного программирования в среде MATLAB следующим образом: » f = [-0.6 -0.6 -0.5 -0.3] ; » А = [111 1; 0.5 0.5 1 2; 2 3 1 4; 1 -1 0 0; 0 1 1 -1; ... -1 -0.25 -0.5 -3; -10 0 0; 0 -1 0 0; 0 0 -1 0; 0 0 0 -1]; » Ь = [50000; 40000; 18000; 0; 0; -10000; 0; 0; 0; 0]; » simlp(f# A# Ь) ans = 1.0е+03 *
312 MATLAB 1.2683 1.2683 1.3171 2.5854 Джейн должна посетить по 1268 домов в Готеме и Метрополисе, 1317 домов в Озе и 2585 домов в Ривер Сити. (б) Если количество времени удваивается, то » Ъ = [50000; 40000; 36000; 0; 0; -10000; 0; 0; 0; 0]; >> simlp(f, A, b) ans = 1.0е+03 * 4.0000 4.0000 0 4.0000 Джейн должна проагитировать по 4000 домов в Готеме, Метрополисе и Ривер Сити и не посещать дома в Озе. (в) Наконец, если, кроме того, она должна собрать вкладов на сумму 20000$, тогда » Ъ = [50000; 40000; 36000; 0; 0; -20000; 0; 0; 0; 0]; >> simlp(?. A, b) ans = 1.0е + 03 * 2.5366 2.5366 2.6341 5.1707
Ответы к практическим занятиям 313 Джейн необходимо посетить по 2537 домов в Готеме и Метрополисе, 2634 дома в Озе и 5171 - в Ривер Сити. 9. Через w, х, у и z мы обозначим число часов, которые Джо тратит с защитником, бегунами, принимающими и судьями на линии соответственно. Тогда линейные неравенства, определенные заданными условиями будут выглядеть следующим образом: • Неотрицательные данные: w ^ 0,х > 0,у^ 0, z > 0; • Доступное время: w + х + у + z < 50; • Получение очков: 0. 5w + О.Зх + 0.4у + O.lz > 20; • Критика: w + 2х + Зу + 0.5z < 75; • Соотношения между игроками: х = у, w ^ х + у# х > z. Величина, которая будет увеличена до наибольшего возможного значения: • Личное удовлетворение: 0 • 2w + 0.4х + О.Зу + 0.6z. (а) На основании этих данных мы можем подготовить и решить предложенную задачу линейного программирования в среде MATLAB следующим образом: » f = [-0.2 -0.4 -0.3 -0.6]; » А = [111 1; -0.5 -0.3 -0.4 -0.1; 12 3 0.5; 0-11 0;... 0 1-1 0; -111 0; 0-10 1; -1 0 0 0; 0 -1 0 0;... 0 0 -1 0; 0 0 0 -1]; » b = [50; -20; 75; 0; 0; 0; 0; 0; 0; 0; 0]; » simlp(f, A# Ь) ans = 25.9259 9.2593 9.2593 5.5556 Джо должен провести по 9.3 часа с бегунами и принимающими, 5.6 часа с судьями на линии и большую часть своего времени, 25.9 часа, с защитником.
314 MATLAB (б) Если для победы команде необходимо только 15 очков, то » Ь = [50; -15; 75; 0; 0; 0; 0; 0; 0; 0; 0] ; >> simlp(?, Л, Ь) ans = 20.0000 10.0000 10.0000 10.0000 в этом случае Джо мог бы распределить свое время более равномерно и провести по 10 часов с бегунами, принимающими и судьями на линии, но, тем не менее, самую большую часть своего времени, 20 часов, ему необходимо было бы провести с защитником. (в) Наконец, если, кроме того, число критических замечаний уменьшается до 70, то » Ъ = [50; -15; 70; 0; 0; 0; 0; 0; 0; 0; 0] ; » simlp(f, А, Ь) ans = 18.6667 9.3333 9.3333 9.3333 Джо должен провести 182Л часа с защитником и по 91/з часа с каждой из трех других групп. Обратите ваше внимание на то, что общее количество получилось меньше 50, оставляя Джо некоторое свободное время. 10. Пусть f будет величиной, которая установлена равной нулю. Это функция напряжения на диоде V, а также параметров V0, R, 10, и VT. Обратите ваше внимание на то, что f должна быть равна нулю для некоторых значений от 0 до V0. » f = @(V, V0, R, 10, VT) V - V0 + R*I0*exp(V/VT);
Ответы к практическим занятиям 315 (а) » fl в <a(V) f(v# 1.5, 1000, 10А(-5), .0025); » VD = fzero(fl, [0, 1.5]) VD = 0.0125 Мы получили напряжение, а ток, следовательно, будет равен » I - A.5 - VD)/1000 I = 0.0015 (б) » f2 = @(V) f(V, 1.5, 1000# 10А(-5)/2, .0025); » fzero(f2# [0, 1.53]) ans = 0.0142 Не удивительно, что напряжение немного повышается. (в) » f2 о <a(v) f(V# 1.5# 1000, 10А(-5), .0025/2); # [0, 1.5]) Error using ==> fzero Function values at interval endpoints must be finite and real. Ошибка состоит в том, что значения показательной функции являются слишком большими в правой конечной точке исследуемого промежутка. Мы должны определить промежуток таким образом, чтобы он получился достаточно большим, дабы можно было найти решение, но, в то же время, и достаточно маленьким, чтобы препятствовать показательной функции слишком сильно увеличиваться в правой конечной точке. Эта особенность проявится еще более заметно в пункте (е) ниже. » ?zero(?2, [0, 0.5])
316 ans = 0.0063 На этот раз напряжение понижается. (г) Далее мы делим на два оба значения: » f2 = ©(V) f(V, 1.5, 1000, 10М-5)/2, .0025/2); » fzero(f2, [0, 0.5]) MATLAB ans = 0.0071 Напряжение получилось меньше, чем в пункте (б), но больше, чем в пункте (в). (Д) » X ш 1О.Л(О:-1:-5); » f3 я <a(V, х) f(V, 1.5, 1000, 10А(-5)*х, .0025*х); >> VD = 0:5; % присвоение начальных значений вектору VD- значений >> for j = 1:6 f4 = @(V) f3 (V, X(j)); VD(j) = fzero(f4, [0, end » loglogA0A(-5)*X# VD, 'x-') » xlabel "I.O1 >> ylabel «V.D1 10
Ответы к практическим занятиям 317 График, построенный с помощью функции loglog, выглядит линейным. То есть, VD примерно равняется постоянной, умноженной на 10. 11. (а) >> dsolve('Dx = х - хА2') ans = l/(l+exp(-t)*Cl) >> syms xO; sol = dsolve('Dx = x - xA2', 'x(O) = xO1) sol = l/(l-exp(-t)*(-l+xO)/xO) Обратите внимание, что это выражение включает нулевое решение. Действительно, >> bettersol = simplify(sol) bettersol = -x0/(-x0-exp(-t)+exp(-t)*x0) >> subs(bettersol, xO, 0) ans = 0 F) Мы уже решили уравнение в пункте (а), таким образом, все, что нам осталось сделать - это заменить начальные условия для хО и отобразить результаты на графике. Мы увеличиваем величину толщины линии Line Width со значения по умолчанию до такой величины, чтобы нулевое решение выделилось лучше. >> Т = 0:0.1:5; >> cla reset; hold on >> solcurves = @(t,xO) eval(vectorize(bettersol));
318 >> for initval = 0:0.25:2.0 plot(T# solcurves(T# initval), «LineWidth1, 1.5) end >> axis tight >> title 'Решение Dx = x - xA2# cx@) =0# 0.25# >> xlabel 't1 >> ylabel Ixl >> hold off Решение Dx = x - x*2, с х@) = 0,0.25,..., 2 2 MATLAB x 1 Графические данные указывают на то, что решение, которое начинается в нуле, остается равным нулю, а все другие решения стремятся к постоянной величине, равной 1. (в) Чтобы использовать команду ode45, мы собираемся записать дифференциальные уравнения как одно уравнение с векторной переменной х. Две составляющие этой переменной представляют два числа х и у. >> cla reset; hold on » f = @(t,x) [x(l) - x(l)A2 - 0.5*x(l)*xB); ... xB) - xB)A2 - 0.5*x(l)*xB)]; » for a = 0:1/12:13/12 for b = 0:1/12:13/12 [t, xa] = ode45(f# [0 3]# [a, b]); plot(xa(:, 1), xa(:, 2))
Ответы к практическим занятиям 319 end end » axis([0 13/12 0 13/12]); hold off 1 0.8 0.6 0.4 0.2 0.2 0.4 0.6 0.8 (г) Конечные точки на кривых являются начальными точками. Таким образом, ясно, что любая кривая, которая начинается в первом секторе, стремится к определенной точке - на графике это примерно B/3; 2/3). Действительно, если х = у = 2/3, то правые стороны обоих уравнений в (С.4) становятся равными нулю, таким образом, производные также равны нулю, а значения x(t) и y(t) остаются постоянными, поскольку они не зависят от t. Если только один вид присутствует в начале (когда кривая начанается на одной из осей), то решение стремится или к точке A; 0), или @;1) - в зависимости от того, какой из видов (х или у) присутствует в начале. Точно такое же поведение мы видели в пункте (б). (д) >> cla reset; hold on » f = <*(t,x) [x(l) - x(l)*2 - 2*x(l)*xB); ... » xB) - xB)A2 - 2*x(l)*xB)]; » for a = 0:1/12:13/12 for b = 0:1/12:13/12 [t, xa] = ode45(f, [0 3]# [a# b]); plot(xa(:, 1), xa(:, 2)) end end » axis([0 13/12 0 13/12]); hold off
320 MATLAB 0.8 0.6 0.4 0.2 0.2 0.4 0.6 0.8 На этот раз большинство кривых, как видно, стремится к одной из точек A; 0) или @; 1) - такое поведение свойственно для любой кривой, которая начинается на одной из осей (то есть, кривой, которая соответствует нулевой начальной численности другого вида). Похоже, что какую бы численность ни имел вид в начале, в конечном счете он достигнет наибольшей численности, а другой вид вымрет. Но есть тонкое равновесие в середине - кажется, что, если эти две численности примерно равны в начале, то они стремятся к определенному распределению численности вида, при котором, если начать из этой области, ничего не изменяется. Эта точка примерно равна A/3; 1/3). Действительно, данная точка отражает случай, когда обе стороны (С.5) равны нулю, и она выполняет такую же роль, что и точка B/3; 2/3) в пункте (в). (е) Модель (С.4) называют «мирное сосуществование», потому что независимо от начальной численности (при условии, что присутствуют оба вида), в конечном счете, выживут оба вида. Модель «судный день» является названием для модели (С.5), поскольку, когда вы начинаете с неравными численностями видов, то меньшая группа вымирает. Более низкий коэффициент 0.5 означает относительно небольшое взаимодействие между видами, допуская их сосуществование. Больший коэффициент 2 приводит к более сильному взаимодействию и к большему соперничеству, которое мешает выживанию обоих видов. 12. Ниже показана модель для программы Simulink, с помощью которой можно повторить выполнение прикладной задачи с маятником из главы 9: >> open_system pendulum
Ответы к практическим занятиям 321 ~И I Индикатор График XY Трение J Интегратор Гравитация Интегратор 1 Тригинометрическая функция При начальных условиях х@) = 0 и х @) = 10 блок XY Graph (График XY) отображает следующий фазовый вид х от х. >> [t, x] = sim('pendulum1); 5 10 XAxis А блок Scope (Индикатор) строит следующий график х как функции от t. » simplot (t, x(:,l)) » axis( [0 30 0 15] ) 11-1605
322 13. MATLAB Ниже показана модель программы Simulink для уравнения движения бейсбольного мяча. >> open_system baseball Интегрировать х" в х' Интегрировать х'вх у против t Способ работы этой схемы довольно прост. Блок Integrator (Интегратор), рас- полженный на схеме вверху слева, интегрирует ускорение (векторную величину), чтобы получить скорость (также вектор). Этот блок требует начального значения скорости как начальное условие. Мы определяем его в блоке Constant (Постоянная), помеченным как «initial velocity» (начальная скорость). Результат из первого блока Integrator (Интегратор) входит во второй такой же блок, который интегрирует скорость, чтобы получить расположение (также вектор). Начальное условие для расположения, [0, 4], хранится в параметрах этого второго блока Integrator (Интегратор). Вектор расположения вводится в блок Demux (Разделитель), который разделяет горизонтальные и вертикальные составляющие расположения. Полученные составляющие передаются в блок XY Graph (График XY), а вертикальная составляющая также подается в блок Scope (Индикатор) так, чтобы мы могли увидеть высоту шара, как функцию от времени. Самая сложная часть заключается в вычислении правой стороны (С.7). Она вычисляется с помощью добавления двух элементов справа с помощью блока Sum (Суммирование), расположенного на схеме внизу слева. Значение [0,-д] сохраняется в блоке Constant (Постоянная) с надписью «gravity» (сила тяжести). Второй элемент справа вычисляется в блоке Product (Произведение), помеченном как «Compute acceleration due to drag» (Вычисление ускорения, вызванного сопротивлением среды), который умножает скорость (вектор) на -с и на скорость (скаляр). Мы вычисляем скорость с помощью скалярного умножения скорости на саму себя и затем извлекаем квадратной корень. Затем мы умножаем полученную величину на -с в блоке Gain (Увеличение), помещенном внизу в середине модели. Блок Scope (Индикатор) внизу справа строит скорость шара как функцию от времени.
Ответы к практическим занятиям 323 (а) Когда значение переменной с установлено равным 0 (нет никакого сопротивления воздуха) и начальная скорость равна [80, 80], мяч следует по траектории, по форме близкой к параболической, как это видно из следующего рисунка. >> [t, x] = sim("baseball1); 150 100 200 300 400 500 XAxis Обратите внимание, что шар перед касанием земли перемещается приблизительно на 400 футов, таким образом, полученное расстояние примерно равно расстоянию, которое требуется для удара на большинстве бейсбольных стадионов. Мы можем узнать время полета и конечную скорость из двух других индикаторов: » simplot (t# x(:,2)) » axis( [0 10 0 150]) >> title 'Height versus Time1 >> simplot(t# sqrt(x(:,3).Л2 » axis([0 10 50 300]) >> title 'Speed versus Time1 х(:,4).А2))
324 MATLAB Таким образом, мяч остается в воздухе приблизительно 5.0 секунд и перемещается примерно со скоросью 115 фут./сек., когда касается земли. (Обратите ваше внимание на то, что моделирование продолжается за пределами этого времени. Поскольку модель не учитывает касание земли, высота продолжает уменьшаться, а скорость продолжает увеличиваться, как будто шар запустили с утеса.) Теперь давайте посмотрим, что получается, когда мы учитываем влияние сопротивления воздуха. Как и ранее, примем начальную скорость равной [80# 80]. Сначала мы установим с = 0,0017. Траектория теперь выглядит следующим образом: » set_param('baseball/Gain1, 'Gain', '-0.00171) sim('baseball'); » [t, x] X Y Plot 400 500 Обратите внимание на большое различие, которое создает сопротивление воздуха: теперь шар перемещается только примерно на 270 футов. Мы можем также исследовать время полета и скорость с помощью двух других индикаторов: » simplot(t, x(:,2)) » axis( [0 10 0 150]) » title 'Height versus Time*
Ответы к практическим занятиям 325 » simplot(t, sqrt(x(:,3) .A2 » axis( [0 10 50 300]) >> title 'Speed versus Time1 х(:#4).А2)) Таким образом, шар достигает наибольшей высоты в воздухе, приблизительно равной 80 футов, и касается земли примерно через 1.5 секунды. (б) Теперь давайте выполним точно такое же вычисление, но примем с = 0.0014 (значение, соответствующее при игре в Денвере). Траектория шара теперь будет » set_param(' baseball/Gain' # 'Gain1, '-0.00141) » [t, x] = sim(¦baseball1);
326 MATLAB 100 100 200 300 400 500 XAxis Шар уходит приблизительно на 285 футов, или приблизительно на 15 футов дальше, чем при игре на уровне моря. На первый взгляд разница в 15 футов может показаться незначительной, но в некоторых трудных для попадания случаях эти дополнительные 15 футов могут означать различие между состоянием вне игры и хорошим ударом. Если мы посмотрим на индикатор высоты для вычислений для игры в Денвере, то мы увидим: » sixnplot(t, x(:,2)) » axis( [0 10 0 150]) >> title 'Height versus Time1 таким образом, есть очень маленькое увеличение времени полета. Точно так же, если мы посмотрим график скорости для игры в Денвере, то мы увидим: » simplot(t# sqrt.(x(:,3).A2 + х(:,4)вА2)) » axis( [0 10 50 300]) >> title 'Speed versus Time1
Ответы к практическим занятиям 327 Итак, конечная скорость получилась немного выше, приблизительно 83 фут./сек. (в) Можно было бы ожидать, что на среднее число отбитых мячей и среднее число заработанных очков будут выше в Денвере, что действительно имеет место согласно статистике Высшей лиги бейсбола. 14. Следующий М-файл решает необходимую задачу: >> type editrecent function editrecent directory = dir('*.m'); if any(size(directory) == 0) error(' М-файлов не найдено.1) end dates = datenum({directory.date}); [maximum, index] = max(dates); edit(directory(index).name) При присвоении результата функции dir переменной мы получаем массив, который содержит, кроме всего прочего, названия всех М-файлов в текущей папке и даты их изменений. Если массив содержит 0 элементов, то мы выводим сообщение об ошибке. В противном случае мы преобразуем даты в матрицу из строк и используем функцию datenum, чтобы преобразовать строки в числа. Мы находим индекс наибольшего числа, указывающий самую последнюю дату, и, наконец, передаем название соответствующего файла команде edit.
328 MATLAB 15. Как предложено в подсказке к этому заданию, мы начинаем с определения массива Z из комплексных чисел, действительные части которых выбираются из вектора xvals, а мнимые части - из вектора yvals. >> xvals = linspace(-2, 2, 400); >> yvals = linspace(-1.5, 1.5, 300); >> [X, Y] = meshgrid(xvals, yvals); » Z = X + i*Y; Затем мы применяем данную функцию 100 раз к каждому числу в массиве. К этому времени большинство последовательностей, которые склонны уходить в бесконечность, уже стали больше, чем наибольшее число с плавающей запятой, которое среда MATLAB может хранить в памяти. » for k = 1:100 Z = Z.A2 - 0.75; end Теперь мы используем функцию isfinite, чтобы присвоить значение 1 для тех элементов в массиве, которые все еще остаются конечными числами с плавающей запятой и 0 - для тех, которые ушли в бесконечность. Затем мы используем функцию imagesc, чтобы раскрасить точки с единицами не так, как точки с нулями. Мы выбрали серую карту цветов, чтобы использовать белые и черные цвета. Наконец, мы используем команду set, чтобы обратить вертикальную ось. Без использования этой команды меньшие числа появились бы наверху графика. Этот режим установлен по умолчанию для функции image и функции imagesc, но математические графики обычно рисуются по-другому. >> elf reset » set(gc?, 'Color1, "White") >> imagesc(xvals, yvals, isfinite(Z)) >> colormap (gray) >> set(gca, "YDir", "normal") >> axis equal tight
Ответы к практическим занятиям 329 Набор Джулии состоит (приблизительно) из границы между черными и белыми областями. Эта граница является примером «фрактали», и вы можете нарисовать множество других фракталей, изменив выражение z2 - 0.75. Например, пробуйте изменить 0.75 на 0.75 + 0. li и посмотрите, к каким результатам это приведет!
Глоссарий Здесь мы приводим описания часто используемых объектов среды MATLAB из следующих шести категорий: операторы, встроенные постоянные, встроенные функции, команды, графические команды, программные конструкции среды MATLAB. Далее мы перечисляем самые важные команды и блоки программы Simulink. Хотя среда MATLAB не различает команды и функции, удобно воспринимать функции среды MATLAB, как обычные математические функции. Функция среды MATLAB может быть вычислена и построена графически, команда же либо обрабатывает данные или выражения, либо запускает некоторую последовательность действий. Ниже приведен список, который содержит операторы, функции или команды вместе с кратким описанием их действия, а также с одним или несколькими примерами. Много команд среды MATLAB могут быть записаны различными способами, потому что эти команды можно применять к различным видам объектов. В наших примерах мы показали наиболее часто используемые виды команд. Немало команд также обладают многочисленными дополнительными параметрами: в данный перечень мы включили только некоторые довольно распространенные параметры. Вы можете найти описание всех команд и получить более полную информацию обо всех дополнительных параметрах, используемых каждой командой, из справочной информации. Для этого вам необходимо набрать или help <название_команды>, или doc <название_команды>. Приведенный список не является полным. Мы выбрали только те команды среды MATLAB, которые играют важную роль в этой книге, а также те, которые, по нашему мнению, окажутся наиболее полезны пользователям. Вы можете найти более подробный список, используя окно Help (Справка). |®> Смотрите раздел «Онлайновая справка» в главе 1 для получения детального описания окна Help (Справка). Операторы среды MATLAB \ Левое матричное деление. X = А\В является решением уравнения А*Х = В. Наберите help slash для получения дополнительных сведений. А = [1 0; 2 1]; В = [3; 5] ; А\В / Обычное скалярное деление или правое матричное деление. Для матриц выражение А/В по существу равнозначно записи A*inv(B). Наберите команду help slash для получения дополнительной информации. * Перемножение скалярных величин или матриц. Смотрите оперативную справку для команды mt imes.
Глоссарий 331 • Это не оператор среды MATLAB. Этот символ (точка) используется совместно с арифметическими операторами, чтобы выполнять действия над массивами поэлементно. Также этот оператор используется для получения доступа к полям массива с определенным строением. а = [1 2 3]; Ь = [4-6 8]; а.*Ь syms х у; solve (x + y-2#x-y); ans.x . * Поэлементное умножение массивов. Смотрите описание предыдущего оператора и оперативную справку для команды times. А Возведение скалярных величин или матриц в степень. Смотрите оперативную справку для команды mpower. .А Поэлементное возведение в степень. Смотрите оперативную справку для команды power. : Оператор диапазона, используемый для определения векторов и матриц. Наберите команду help colon для получения дополнительных сведений. , Разделяет элементы строки матрицы или параметры команды. Может также использоваться, чтобы разделять команды в командной строке. ; Запрещает вывод результата команд MATLAB, может использоваться, чтобы отделять команды в командной строке. Также используется для разделения строк матрицы или вектора-столбца. X = 0:0.1:30; [1; 2; 3] ' Сопряженное комплексное транспонирование матрицы. Смотрите команду ctranspose. Также устанавливает границы для начала и конца строки. .' Транспонирование матрицы. Смотрите команду transpose. ... Оператор продолжения строки. Не может использоваться внутри строк в кавычках. Наберите команду help punct для получения дополнительных сведений. 1+3+5+7+9+11... + 13 + 15 + 17 ['С этим оператором можно создать длинные строки# занимаю1 • • • ¦щие более 1 линии. Обратите внимание на квадратные скобки.•]
332 MATLAB ! Выполняет команду из операционной системы. Для приведенного ниже примера файл program.bat должен быть создан заранее в директории Programs на диске С. ! С: \ Programs \program. bat % Комментарий. Среда MATLAB пропустит оставшуюся часть строки. %% Начинает новую ячейку (если данный оператор встречается в начале строки в тексте М-файла). @ Создает идентификатор функции или безымянную функцию. fminbnd(@cos, 0, 2*pi) f = <?(х) х.А2 - х Встроенные постоянные eps Примерно равна ошибке округления компьютера при действиях с плавающей запятой, на большинстве компьютеров ошибка приблизительно равна 2x10 16 ехр A) е = 2.71828. ... Обратите внимание, что нет константы е, а переменная е не содержит никакого определенного значения. i i = V-1. Данное присвоение можно отменить, например, если вы хотите использовать переменную i в качестве индекса в цикле for. В этом случае для обозначения мнимой единицы может использоваться переменная j. Inf °° (обозначение бесконечности). То же, что и inf. NaN Обозначение нечисловых значений («Не число» (Not a Number)). Используется для неопределенных выражений, например, для 0/0. pi п= 3.14159. • ..(число «пи»). Встроенные функции abs |x| (модульх). acos арккосинус х. asin арксинус х. atan арктангенс х. Используйте функцию a tan 2 вместо a tan, если вам необходима угловая координата 9 точки (х, у).
Глоссарий 333 Bessel Функции Бесселя: besselj (n, х) и bessely (n, x) являются линейно независимыми решениями уравнения Бесселя n-го порядка. conj Создает сопряженное комплексное число для заданного комплексного числа. conj(l - 5*i) cos косинус х. cosh гиперболический косинус х. cot котангенс х. erf функция ошибок erf (х\ _ ^ ехр ех (экспонента для числа е). expm Матричная экспонента. gamma Гамма-функция Г (х) = Гe~'tx~ldt (когда Re х > 0). imag imag (z), мнимая часть комплексного числа. log натуральный логарифм In х = logeX. real real (z), действительная часть комплексного числа. sec секанс х. sech гиперболический секанс х. sign Возвращает -1, 0 или 1 в зависимости от того, является ли параметр данной функции отрицательным числом, нулем или положительным значением. sin синус х. sinh гиперболический синус х. sqrt Vx (квадратный корень числа), tan тангенс х. tanh гиперболический тангенс х. Команды среды MATLAB Addpath Добавляет указанную папку к списку путей, которые среда MATLAB использует для поиска файлов. addpath C:\my_mfiles
334 MATLAB axis Переменная, которая хранит значение последнего результата, если он не был присвоен какой-либо переменной. cd Делает указанную папку текущей (рабочей) папкой. cd C:\xnydocs\mfiles char Преобразовывает символьное выражение в строку. Используется при определении встраиваемых функций. syms х у; f = inline (char (sin (x) * sin (y))) clear Очищает значения переменных и определения для функций. Если вы определите одну или более переменных, то только эти указанные переменные будут очищены. clear clear ? g collect Собирает коэффициенты для определенной символьной переменной в заданном символьном выражении. syms х у; collect(хЛ2 - 2*у*хА2 + 3*х + х*у# х) compose Композиция функций. syms х у; f = exp(x); g = sin(у); h = compose(f, g) ctranspose Сопряженное транспонирование матрицы. Обычно используется совместно с оператором ¦. Данная команда равносильна команде transpose для действительных матриц. А - [1 3 i] А1 D Это не совсем команда среды MATLAB. Используется в команде dsolve, чтобы обозначить дифференцирование. Смотрите dif f. dsolve('x*Dy + у = sin(xI, 'x') delete Удаляет файл. delete <?ilename> det Определитель матрицы. det([l 3; 4 5]) diag Создает квадратную матрицу с определенным диагональным вектором или выделяет диагональ в квадратной матрице. V = [2345]; diag(V) X = [2 3; 4 5]; diag(X) diary Записывает ход сеанса работы среды MATLAB в файл.
Глоссарий 335 diary <filename> diary off dif f Оператор символьного дифференцирования (также оператор приращения). syms х; diff(хЛ3) diff(Ix*yA2I, 'у1) dir Отображает список файлов в текущей рабочей папке. Эта команда подобна команде Is. Disp Отображает результат. х = 5.6; disp(x) syms x; disp(xA2) disp ('Эта строка будет напечатана без кавычек.1) doc Открывает документацию по определенной команде в обозревателе справки. doc print double Получает значение двойной точности как для численной, так и для символьной величины. Если применить команду double к строке, то будет выдан вектор кодов ASCII для знаков в строке. z = sym(fpi'); double(z) doublet-think1) dsolve Инструмент символьного решения ОДУ. По умолчанию независимой переменной является t, но можно указать и другую переменную (для этого служит последний параметр этой команды). dsolve(fD2y - х*у = О1, 'х1) dsolvefDy + уА2 = О1, 'у(О) = 1', 'х') [х, у] = dsolve('Dx = 2х + у"# ¦Dy = -х1) echo Включает или отключает отображение «эхоконтроль» команд из М-файла. edit Открывает указанный М-файл в редакторе/отладчике. edit mymfile eig Вычисляет собственные значения и собственные векторы квадратной матрицы. eig([2, 3; 4, 5]) [е, v] = eig([l, 0# 0; 1, 1, 1; 1, 2# 4]) end Последний элемент вектора, а также команда программирования.
336 MATLAB v(end) vC:end) eval Вычисляет строку, как выражение среды MATLAB. Эта команда применяется в М-файлах. eval (• cos (х) ¦) expand Раскрывает алгебраическое выражение. syms х у; expand((х - у)А2) eye Единичная матрица указанного размера. еуеE) factor Разлагает на множители полином или целое число. syms х у; factor(хА4 - уА4) f eval Вычисляет функцию, заданную в виде строки. Эта команда может оказаться полезной в М-файлах функций. fevaK'exp1, 1) find Находит индексы элементов, отличных от нуля, для вектора или матрицы. X = [2 0 5]; find(X) Fminbnd Находит наименьшее (приблизительное) значение функции на каком- либо промежутке. fminbnd(@(x) хА4 - хА2 + 1, 0, 1) format Определяет формат результата для числовых переменных. format long f zero Пытается найти нуль для указанной функции около заданной начальной точки или на указанном промежутке. fzero(@(x) cos(x) - х, 1) fzero(@cos, [-pi 0]) guide Открывает окно проектирования графической среды пользователя (GUI). guide mygui help Запрашивает документацию для определенной команды среды MATLAB. Смотрите также команду lookf or. help factor inline Создает встраиваемую функцию среды MATLAB из строкового выражения.
Глоссарий 337 f = inline('xA5 - x'); fC) int Оператор интегрирования. Этот оператор используется как для определенных, так и для неопределенных интегралов. int('l/(l + хА2)', "х1) syms x; int(exp(-x), х, 0, Inf) inv Инверсия квадратной матрицы. inv([l 2; 3 5]) j ас obi an Вычисляет матрицу Якобиана или, для скалярной функции, символьный градиент. syms х у; f = хА2*уА3; jасobian(f) length Выдает число элементов в векторе или строке, length('abode') limit Находит двухсторонний предел, если он существует. Используйте 'right' или ' left' для поиска односторонних пределов. syms x; limit(sin(х)/х, х, 0) syms x; limit(l/x/ x, Inf, 'left') linspace Создает вектор линейно распределенных точек. linspace@, 2*pi, 30) load Загружает переменные рабочего пространства из файла на диске. load filename lookfor Ищет указанную строку в первой строке всех М-файлов, найденных в пути среды MATLAB. look for ode Is Перечисляет файлы в текущей рабочей папке. Эта команда подобна команде dir. maple Обеспечивает прямой доступ к ядру пакета Maple. Данная команда недоступна в варианте программы Student Version. maple ('csgn'# '-1+i') mhelp Запрашивает ядро пакета Maple для нахождения справки о команде Maple. Данная команда не доступна в варианте программы Student Version. mhelp csgn max Находит в векторе элемент с наибольшим значением. X = [3 5 1 -6 23 -56 100]; хпах(Х)
338 MATLAB mean Вычисляет среднее арифметическое элементов вектора. Х= [3 5 1 -б 23 -56 100]; mean(X) Median Вычисляет медиану элементов вектора. X = [3 5 1 -б 23 -56 100]; median(X) min Находит в векторе элемент с наименьшим значением. X = [3 5 1 -б 23 -56 100]; min(X) more Включает (или отключает) постраничное прокручивание результата в среде MATLAB. Используйте клавишу II пРр6ел |. чтобы перейти к следующей странице, клавишу 'Enterl. чтобы перемещаться построчно (строка за строкой), клавишу ¦ QI. чтобы прервать вывод результата. more on, help print more off notebook Открывает М-книгу (только для операционной системы Windows). notebook probleml.doc notebook -setup num2str Преобразовывает число в строку. Полезная команда в программировании. disp(["Занчение pi равно ', num2str(pi)]) ode4 5 Инструмент численного решения ОДУ для уравнений первого порядка. Смотрите оперативную справку среды MATLAB для команды ode45, чтобы познакомиться со списком других инструментов решения ОДУ, доступных в среде MATLAB. [t, у] = ode45«a(t, у) t*2 + y# [0 10] , 1); plot(t/ у) ones Создает матрицу из единиц. onesC) onesC, 1) open Открывает файл. При использовании этой команды необходимо учитывать расширение в имени файла. open myfigure.fig path Без какого-либо параметра данная команда отображает путь поиска, с параметром - устанавливает путь поиска. Наберите команду help path для получения подробных объяснений.
Глоссарий 339 pathtool Открывает окно инструмента Set Path (Установка пути). Pretty Показывает символьное выражение в более легком для восприятия виде. syms х у; ехрг = х/(х - 3)/(х + 2/у) pretty(expr) prod Вычисляет произведение элементов вектора. X = [3 5 1 -б 23 -56 100]; prod(X) publish Выполняет М-файл и публикует его. В качестве режима по умолчанию установлена публикация в формате HTML, но вы можете определить другие форматы. publish*'mymfile1, 'latex1) pwd Показывает название текущей (рабочей) папки. quadl Команда численного интегрирования. В среде MATLAB 5.3 или более ранних версиях вместо указанной команды используйте команду quad8. format long; quadl(G(x) sin(exp(x)), 0, 1) g = inline('sin(exp(x))¦); quad8(g, 0, 1) quit Завершает сеанс работы среды MATLAB. rand Генератор случайных чисел. Эта команда позволяет создавать массивы случайных чисел от 0 до 1. randn Нормальный генератор случайных чисел. Создает массивы случайных чисел, распределенных по нормальному закону, со средним значением 0 и дисперсией 1. rank Определяет ранг матрицы. А = [2 3 5; 4 б 8]; rank(А) roots Находят корни полинома, коэффициенты которого задаются элементами вектора. roots ([1 2 2]) round Округляет число к наиболее близкому целому числу. save Сохраняет переменные рабочего пространства в указанный файл. Смотрите также команды diary и load. save filename simple Пытается упростить выражение, используя разнообразные методы. syms х у; [expression, how] = simple(sin(x)*cos(y) + cos(x)*sin(y))
340 MATLAB simplify Пытается упростить выражение символически. syms x; simplifyd/A + х) А2 - 1/A - х)А2) size Выдает число строк и число столбцов в матрице. А = [1 3 2; 4 1 5] [г, с] = size(A) solve Решает уравнение или систему уравнений. Если правая сторона уравнения опущена, то предполагается, что она равна нулю. solveС2*х*2 - 3*х +6') [х# у] = solve('x + 3*у = 41, ¦-х - 5*у = З1, 'х1, 'у1) sound Воспроизводит вектор через динамики компьютера. sound(sin(@:0.1:1000)*pi)) str2num Преобразовывает строку в число. Эта команда полезна в программировании. constant = •а7¦ index = stг2пшп(constantB)) subs Заменяет различные части в выражениях. subs('xA3 - 4*х + I1, 'х1, 2) subs('sin(х)Л2 + cos(xI, 'sin(xI, 'z') sum Суммирует вектор или столбцы матрицы. к = 1:10; sum(k) sym Создает символьную переменную или число. sym pi х = sym( 'x') constant = sym(ll/2l) syms Определяет символьные переменные. Команда syms x равносильна записи х = sym (¦х¦). syms x у z symsum Выполняет символьное суммирование вектора, возможно с бесконечно большим числом элементов. syms х k n; symsum(xAk, к, 0, п) syms n; symsum(nA(-2), n, I, Inf) t ay lor Вычисляет полиномиальное приближение Тейлора с указанным числом элементов (в режиме по умолчанию оно равно 6) в указанной точке (в режиме по
Глоссарий 341 умолчанию - в 0). Примечание: число элементов включает постоянный элемент, таким образом, в режиме по умолчанию создается полином пятой, а не шестой степени. syms x; taylor(cos(x), 8, 0) taylor(exp(l/x)# 10, Inf) transpose Транспонирование матрицы (сравните с командой с transpose). Преобразует вектор-столбец в вектор-строку и наоборот. Обычно используется с оператором • ¦. А = [1 3 4] А. ¦ type Отображает содержание указанного файла. type myfile.m vectorize Преобразовывает символьное выражение в векторную форму. Эта команда может быть полезна при определении встраиваемых функций. f = inline(vectorize('хА2 - 1/х1)) vpa Вычисляет выражение до указанной степени точности, используя арифметику переменной точности. vpaCl/3', 20) web Открывает обозреватель Интернета. web (¦ ht tp: / /www • mathworks • com¦) which Отображает путь к файлу указанной команды. which ezplot which ezplot -all whos Выводит список с текущей информацией относительно всех переменных в рабочем пространстве. zeros Создает матрицу нулей. zerosA0) zerosC, 1) Графические команды area Создает закрашенный график области между осью X и кривой. X = @:0.01:4)*pi; Y = sin(X); area(X, Y) axes Создает пустое графическое окно.
342 MATLAB axis Определяет масштаб и вид оси. axis ( [xmin xmax ymin ушах] )-устанавливает диапазоны для осей. axis tight - устанавливает пределы оси для полного диапазона данных. axis equal - делает горизонтальные и вертикальные масштабы равными. axi s square - делает вид изображения квадратным (оси равны по длине). axis off - скрывает отметки на осях и сами оси. bar Рисует гистограмму. Ьаг([2, 7, 1.5, б]) cla Очищает оси. close Закрывает текущее графическое окно, команда close all закрывает все графические окна. colormap Определяет особенности карты цветов для текущего рисунка. Наберите команду help graph3d, чтобы посмотреть примеры карт цветов. ezmesh sin(x)*cos(y); colormap cool comet Отображает анимированный параметрический график. t = @:0.01:4)*pi; comet(t.*cos(t)# t.*sin(t)) contour Строит линии уровня функции двух переменных, обычно используется с командой meshgrid. [Х# Y] =meshgrid(-3:0.1:3, -3:0.1:3); contour(X# Y, Х.А2 - Y.A2) contourf Заполненный график контура. Часто используется вместе с командой colormap. [X,Y] =meshgrid(-2:0.1:2 # -2:0.1:2); contourf(X, Y, X.A2 - Y.A3); colormap autumn ezcontour Простая команда для построения графиков контуров или линий уровня. ezcontour('хА2 - уЛ2') syms х у; ezcontour(х - уА2) ezmesh Простая команда для построения поверхностей. ezmesh((хА2 + уА2')
Глоссарий 343 syms x у; ezmesh(x*y) ezplot Простая команда для построения символьных выражений. ezplot('ехр(-хЛ2)', [-5, 5]) syms x; ezplot(sin(x)) ezplot 3 Простая команда для построения трехмерных параметрических кривых. ezplot3Ccos(t) ', 'sin(tI, 't1) syms t; ezplot3(l - cos(t), t - sin(t), t, [0 4*pi]) ezsurf Простая команда для построения видов поверхностей, закрашенных по определенному образцу. ezsurf('(xA2 + уЛ2)*ехр(-(хА2 + yA2))') syms х у; ezsurf(sin(x*y), [-pi pi -pi pi]) figure Создает новое графическое окно, fill Создает заполненный многоугольник. Смотрите также команду patch. fill([0 110], [0011], 'b'); axis equal tight f indob j Находит графические объекты с указанными значениями свойств. findobj(•Type¦, ¦Line") gca Получает текущие оси. gcf Получает текущий рисунок. get Получает свойства рисунка. get(gcf) get frame Эта команда используется, чтобы получить кадры фильма или анимации. Т = @:0.01:2)*pi; for j = 1:12 plotE*cos(j*pi/6) + cos(T), 5*sin(j*pi/6) + sin(T)); axis([-6 6 -6 6]); M(j) = getframe; end movie (M) ginput Собирает координаты из рисунка, используя мышь (нажмите клавишу ltEnterl. чтобы закончить выполнение этой команды).
344 MATLAB [X, У] = ginput grid Помещает сетку на рисунок, gtext Помещает текстовую отметку, используя мышь. gtext(¦Region of instability1) hist Рисует гистограмму. hist(randB00, 1)) hold Сохраняет текущий график. Накладывает любые новые графики, созданные средой MATLAB, поверх текущего рисунка. hold on hold off image Отображает матрицу, как изображение. image(onesE0, 100)) imagesc Действует так же, как и команда image, но масштабирует данные в случае необходимости. imagesc(randnE0# 100)) imread Читает графический файл и преобразовывает его в матрицу. Л = imread (' myimage. jpg') ; imwrite Преобразовывает матрицу в графический файл. imwrite(A, 'picture.jpg1) legend Создает легенду для рисунка. t = 0:0.1:2*pi; plot(t# cos(t), t# sin(t)) legend('cos(t)', 'sin(t)') log log Создает график в двойном логарифмическом масштабе. х = 0.0001:0.1:12; loglog(x, x.A5) mesh Рисует поверхность с сеткой. [X,Y] =meshgrid(-2:.l:2, -2:.1:2); mesh(X, Y, sin(pi*X).*cos(pi*Y)) shgrid Создает векторный массив, который может использоваться как входной параметр для графической команды, например, для команд contour, quiver или surf. [X, Y] = meshgrid@:0.1:l, 0:0.1:2) contour(X, Y, X.A2 + Y.A2)
Глоссарий 345 movie Воспроизводит фильм. Смотрите также команду get frame. movieview Эта команда подобна команде movie, но появляется кнопка для воспроизведения. patch Создает заполненный многоугольник или закрашенный участок поверхности. Смотрите также команду fill. t = @:l:5)*2*pi/5; patch(cos(t), sin(t)/ 'r'); axis equal pie Рисует секторный график на основании данных в векторе. Z = [34 5 32 6]; pie(Z) plot Строит векторы данных. X = [0:0.1:2]; plot(X# Х.А3) plot3 Строит кривые в трехмерном пространстве. t = [0:0.1:30]; plot3(t, t.*cos(t), t.*sin(t)) polar Команда для построения графика в полярных координатах. theta = @:0.01:2)*pi; rho = theta; polar(theta, rho) print Отправляет содержание текущего графического окна на принтер или в файл. print print -deps picture.eps quiver Строит (числовое) векторное поле на плоскости. [х, у] =meshgrid(-4:0.5:4, -4:0.5:4); quiver(х, у, х.*(у - 2)# у.*х); axis tight semi logy Создает график с логарифмическим масштабом по вертикальной оси. х = 0:0.1:12; semilogy(x, ехр(х)) set Устанавливает свойства рисунка. set(gcf, 'Color', [0, 0.8, 0.8]) subplot Разбивает графическое окно на сетку из меньших графиков. subplotB, 2, 1), ezplot('xA2') subplotB, 2, 2), ezplot('xA3') subplotB, 2, 3), ezplot('xA4') subplotB, 2, 4), ezplot('xA5')
346 MATLAB surf Рисует непрерывную поверхность. [X,Y] =meshgrid(-2:.1:2, -2:.1:2); surf(X, Y# sin(pi*X) •*cos(pi*Y)) text Комментирует рисунок с помощью размещения текста в указанных координатах. text(x, у, 'string1) title Назначает заголовок для текущего графического окна. title 'Nice Picture' xlabel Определяет подпись для горизонтальной оси координат. xlabel('Year') ylabel Назначает подпись для вертикальной оси координат. ylabel (¦Population¦) view Определяет точку просмотра, из которой будет показан трехмерный график. ezsurf('(xA2 + уА2)*ехр(-(хА2 + уА2))'); view([0 0 1]) syms х у; ezmesh(x*y); view( [1 0 0]) zoom Изменяет масштаб рисунка на указанную величину. Команда zoom без параметров позволяет использовать мышь для увеличения или уменьшения рисунка. zoom zoomD) Программирование в среде MATLAB Any Возвращает истину, если любой из элементов массива отличен от нуля. if any(imag(x) ~= 0); error('Необходимо ввести вещественные числа.¦); end all Возвращает истину, если все элементы массива не равны нулю. break Прерывает выполнение цикла for или while. case Используется для разделения вариантов после оператора выбора switch, computer Выводит тип компьютера, на котором выполняется среда MATLAB. dbclear Очищает проверочные точки в файле. dbclear all dbcont Позволяет вернуться к М-файлу после остановки в проверочной точке.
Глоссарий 347 dbstep Построчно выполняет М-файл после остановки в проверочной точке. dbstop Вставляет проверочную точку в файл. dbstop in <имя__файла> at <номер_строки> dbquit Завершает выполнение М-файла после остановки в проверочной точке. dos Выполняет команду из операционной системы, сохраняя результат в переменной. Эта команда подобна команде unix. end Завершает условный оператор if, циклы for, while или оператор выбора switch. else Альтернативный вариант в условном операторе. Смотрите if. elseif Вложенная альтернатива в условном операторе. Смотрите оперативную справку для оператора if. error Отображает сообщение об ошибке и прерывает выполнение М-файла. find Сообщает номера элементов массива, которые отличны от нуля. n = find(isspace(mystring)); if ~isempty(n) firstword = xnystring(l:n(l) - 1); restofstring = mystring(n(l)+l:end); end for Начинает цикл. Этот оператор должен быть завершен с помощью команды end. close; axes; hold on t = -1:0.05:1; for k = 0:10 plot(t, t.Ak) end function Используется в первой строке М-файла, чтобы определить М-файл- функцию. function у = myfunction(x) if Позволяет задать условие выполнения операторов среды MATLAB. Этот оператор должен быть завершен с помощью команды end. if (x >= 0) sqrt(x) else
348 MATLAB error ('Неверный входной параметр•') end input Приглашает пользователя ввести данные. answer = input('Пожалуйста, введите координаты [х, у]: ') isa Проверяет класс объекта (double, sym и т.д.). isa(x, 'sym') ischar Возвращает истину, если массив является строкой символов. Is empty Возвращает истину, если массив пуст. Isequal Проверяет, равны ли два массива. В отличие от оператора ==, не создает сообщение об ошибке, если сравниваются массивы с различными размерами. isequal([1 2], [12 3]) isfinite Проверяет, конечны ли элементы массива. isfinite([l 0 1]./[1 0 0]) ishold Возвращает истину, если в настоящий момент установлен режим hold on. Isinf Проверяет, бесконечны ли элементы массива. isinf( [1 0 1] ./[1 0 0] ) is letter Проверяет, являются ли элементы строки буквами алфавита. str = 'remove my spaces'; str(isletter(str)) isnan Проверяет, являются ли элементы массива «не числом» (такие элементы могут получаться из неопределенных форм, таких как 0/0). isnan([-l 0 1]/0) isnumeric Возвращает истину, если рассматривается объект численного класса. Ispc Возвращает истину, если среда MATLAB выполняется на компьютере под управлением операционной системы Windows. Isreal Возвращает истину, если массив состоит только из действительных чисел. Is space Проверяет, являются ли элементы строки пробелами, символами табуляции и т.д. Isunix Возвращает истину, если среда MATLAB выполняется на компьютере под управлением операционной системы UNIX. Keyboard Возвращает управление из М-файла на клавиатуру. Эта команда используется при отладке М-файлов. тех Компилирует программу МЕХ. Mlint Проверяет М-файл на присутствие общих синтаксических ошибок.
Глоссарий 349 mlint mymfile nargin Возвращает число входных параметров, переданных М-файлу-функции. if (nargin < 2); error('Неправильное количество параметров'); end nargout Выдает число выходных параметров для М-файла-функции. Otherwise Используется, чтобы отделить дополнительный вариант после оператора выбора switch. Pause Приостанавливает выполнение М-файла до тех пор, пока пользователь не нажмет клавишу. Return Досрочно заканчивает выполнение М-файла или позволяет вернуться к М-файлу после вызова команды keyboard. if abs(err) < tol; return; end switch Этот оператор сходен с оператором if, но позволяет выполнять переход к более чем двум случаям. Этот оператор должен быть завершен с помощью команды end. switch num case 1 dispffla. •) case 0 dispCHeT. ¦) otherwise disp('Возможно.') end unix Выполняет команду из операционной системы, сохраняя результат в переменной. Эта команда подобна команде dos. Varargin Используется в М-файлах-функциях, чтобы обращаться с переменным числом входных параметров. Varargout Используется в М-файлах-функциях, чтобы разрешить использование переменного числа результатов. Warning Отображает предупредительное сообщение. warning ('Извлечение квадратного корня ид отрицательного числа.¦)
350 MATLAB while Повторяет последовательность команд до выполнения заданного условия. Этот оператор должен быть завершен с помощью команды end. mysum = 0; х = 1; while x > eps mysum = mysum + x; x = x/2; end mysum Команды программы Simulink f ind_system Находит название необходимой системы программы Simulink. find__system(gcs, 'Type1, 'block1 ) gcs «Определение текущей системы». Возвращает название текущей модели программы Simulink. get_param Получает параметры блока или системы программы Simulink. open_system Открывает модель программы Simulink. set_param Устанавливает параметры блока или системы программы Simulink. sim Запускает модель программы Simulink. sim('model', [0, 2 0]) simlp Решает задачи линейного программирования. simlp([-l -1], [1 4; 2 3; 4 1], [3; 2; 3]) simplot Строит данные в стиле блока Scope (Индикатор) из программы Simulink. В большинстве отношений эта команда подобна команде plot. simulink Открывает библиотеку программы Simulink. Блоки Программы Simulink Блок Algebraic Constraint (Алгебраическое ограничение) (библиотека Math Operations (Математические действия)). Инструмент для решения уравнений, похож на команду f zero. Блок Clock (Часы) (библиотека Sources (Источники)). Выдает время при моделировании.
Глоссарий 351 Блок Constant (Постоянная) (библиотека Sources (Источники)). Выдает определенную постоянную величину (константу). Блок Demux (Разделитель) (Библиотека Signal Routing (Разводка сигнала)). Разбирает векторный сигнал на составляющие. Блок From Workspace (Из рабочего пространства) (библиотека Sources (Источники)). Получает входной параметр из рабочего пространства среды MATLAB. Блок Gain (Увеличение) (библиотека Math Operations (Математические действия)). Умножает на постоянную величину или на постоянную матрицу. Блок Integrator (Итегратор) (библиотека Continuous (Длительные)). Вычисляет определенный интеграл, используя указанное начальное условие. Блок Math Function (Математическая функция) (библиотека Math Operations (Математические действия)). Вычисляет показательные функции, логарифмы и т. п. Блок Мих (Объединитель) (Библиотека Signal Routing (Разводка сигнала)). Собирает скалярные сигналы в векторный сигнал. Блок Polynomial (Полином) (библиотека Math Operations (Математические действия)). Вычисляет полиномиальную функцию. Блок Product (Произведение) (библиотека Math Operations (Математические действия)). Умножает или делит сигналы. Может также инвертировать матричные сигналы. Блок Ramp (Пилообразный сигнал) (библиотека Sources (Источники)). Создает функцию, которая сначала постоянна, а затем, начиная с определенного времени, линейно увеличивается. Блок Scope (Индикатор) (библиотека Sinks (Приемники)). Строит график сигнала, как функцию от времени. Блок Sine Wave (Синусоида) (библиотека Sources (Источники)). Создает синусоидальные колебания. Вы можете отрегулировать амплитуду, частоту и фазу колебаний. Блок Sum (Суммирование) (библиотека Math Operations (Математические действия)). Складывает или вычитает входные данные. Блок То Workspace (В рабочее пространство) (библиотека Sinks (Приемники)). Выводит сигнал в рабочее пространство среды MATLAB. Блок Trigonometric Function (Тригонометрическая функция) (библиотека Math Operations (Математические действия)). Вычисляет тригонометрические или гиперболические функции. Блок Unit Delay (Единичная задержка) (библиотека Discrete (Дискретные элементы)). Этот блок может оказаться полезным в моделировании с приращениями или в дифференциальных/разностных уравнениях. Блок XY Graph (График XY) (библиотека Sinks (Приемники)). Строит график одного сигнала в зависимости от другого.
Отдел распространения группы издательств «ТРИУМФ» • «Издательство Триумф» • «Лучшие книги» • «Технический бестселлер» • «Только для взрослых» • «Технолоджи - 3000» • «25 КАДР» • «100 КНИГ» Телефон: D95) 772-19-56, D95) 720-07-65. E-mail: opt@triumph.ru Интернет-магазин «Три ступеньки» : www.3st.ru КНИГА-ПОЧТОЙ: 125438, г.Москва, а/я 18 «Триумф». E-mail: post@triumph.ru Группа издательств «ТРИУМФ». Россия, 125438, г. Москва, а/я 18. Подписано в печать с оригинал-макета 24.07.2007 г. Формат 70x1001/i6. Печать офсетная. Печ. л. 22. Заказ № 1605. Тираж 3500 экз. Отпечатано в полном соответствии с качеством предоставленных диапозитивов в ОАО «Можайский полиграфический комбинат» 143200, г. Можайск, ул. Мира, 93