От редактора: предлагая вашему вниманию наброски
книги под условным (и придуманным мной) названием, мы рассчитываем,
что они найдут не только своего читателя, но и со-участника этой
работы. Заинтересованным просьба обращаться к автору по почте или в
специальный раздел Линуксфорума, посвященный обсуждению этой книги.
От автора: Начата работа над книгой, посвящённой
математическому ПО под POSIX-совместимые системы. Тема это почему-то
до сих пор остаётся без пристального внимания, и, как оказалось,
очень даже зря. Начав подыскивать софт, я с удивлением обнаружил,
что даже среди только свободного софта есть представители, на всех
более-менее распространённых задачах не уступающие проприетарным
аналогам. А так как кроме таких, в некотором роде, универсальных
программ есть ещё и очень интересные узко-специальные инструменты,
огромное количество которых разрабатывается именно под упомянутые
POSIX-совместимые системы, то всё вместе это богачество заслуживает
со стороны научного мира внимания как минимум не меньшего, чем столь
популярное ПО под не скажу какую систему.
Вашему вниманию предлагается начало вступительной части и начало
первой (и, возможно, наиболее объёмной) главы, посвящённой самой
серьёзной и универсальной свободной программе, ориентированной на
символьные вычисления – Максиме. В данном варианте рассмотрена
версия 5.9.0, доступная на середину осени 2004 года. В окончательном
же варианте, естественно, весь материал будет приведен в
соответствие с самой свежей версией на момент выхода книги; сейчас
(5.02.05), например, таковой уже является 5.9.1, имеющая по
сравнению с описанной в том числе косметические отличия в
интерфейсе.
На данный момент наблюдается острая нехватка практических
материалов, на которых можно продемонстрировать возможности такого
вида ПО; посему буду весьма благодарен тем, кто сможет предоставить
достаточно интересные и наглядные задачи из различных разделов
математики. Также рад буду общению с людьми, уже имеющими некоторый
опыт работы со свободными математическими программами. Просьба
писать на адрес, указанный в начале этого материала.
Введение
0.1 Несколько слов о компьютерной математике вообще
Так как всю разнообразную функциональность всех программ, о
которых пойдёт речь в этой книге, часто объединяют под термином
«компьютерная математика», поговорим немного для начала о самой
компьютерной математике, вернее о том, что же это такое.
Фраза «компьютерная математика» объединяет в себе два, в
общем-то, мало пересекающихся, смысла. Первый ближе к
прилагательному из этой фразы. Если отвлечься от ныне столь
привычного значения слова «компьютер» и обратиться просто к
английскому языку, из которого это слово пошло, мы получим, что
«компьютерная» означает «вычислительная». Одна функциональность
таких программ – это и есть их большие возможности в
вычислениях, то есть в численных расчётах. В этом смысле программу
такого рода можно использовать как «калькулятор с высшим
математическим образованием», позволяющий проводить численные
расчёты с большой, или даже неограниченной (ничем, кроме памяти
компьютера), точностью и базируясь на целой энциклопедии заложенных
в него знаний из математики и других наук.
Это уже очень много, и одновременно очень мало. Так как любой
человек, сталкивающийся с любым видом научной деятельности,
связанной так или иначе с численными расчётами, начиная от
студенческих курсовых работ, и вплоть до собственных фундаментальных
исследований и монографий, может вспомнить об ещё одной, не менее
важной и, пожалуй, более сложной составляющей таких работ –
теоретических выкладках. Тут как раз и заходит речь о второй
ипостаси компьютерной математики и втором смысле этого названия,
близкому скорее к входящему в него существительному. Здесь
проявляется уже другая возможность компьютеров – оперировать с,
вообще говоря, любыми объектами, природу которых человек сможет
чётко описать. А описаны на сегодняшний день уже практически все
известные человеку математические объекты – от алгебраических
чисел до самого понятия числового поля, от правил вычисления
производной до интегро-дифференциальных уравнений от одной или
нескольких переменных, от определения вектора до принципов
тензорного анализа, и так далее, и так далее... А если вам
понадобится работать с объектом, структура которого в программу ещё
не заложена, вы сможете сами его описать – большинство таких
программ легко расширяемы. Действия со всеми описанными внутри неё
объектами программа компьютерной математики, оперирующая их
описаниями, обычно может представлять в привычной человеку
математической нотации. Эту сторону возможностей математических
программ называют символьной математикой.
Каждая из описанных далее программ обладает в той или иной
степени и одним, и другим из вышеназванных свойств. Одни из них
больше ориентированы на численные расчёты, другие – на
символьное представление данных и символьные (точные) решения. Это
даёт возможность выбрать более подходящий инструмент именно под свои
конкретные задачи. Но основная мощь сокрыта именно в переплетении
этих двух разниц: вы можете, к примеру, точно вывести в символьном
виде коэффициенты дифференциального уравнения, а потом, в случае
невозможности или отсутствия необходимости его точного решения,
посчитать некоторое конкретное решение численно в любых заданных
точках; или приблизить отрезком ряда Тейлора любого порядка; или
построить интегральную линию по тем же численным значениям,
подсчитанным с любой нужной точностью, на плоскости или в трёхмерном
пространстве.
Все эти возможности каждой программы мы изучим сначала каждую по
отдельности, а потом рассмотрим их в совокупности на конкретных
практических примерах.
Глава 1 Maxima – максимум свободы символьных
вычислений.
1.1 Что собой представляет и откуда есть пошла Maxima.
Maxima среди интересующих нас программ обладает самыми широкими
возможностями по части символьных вычислений; это единственная из
открытых программ, способная поспорить в этой области с
коммерческими Mathematica и Maple, переваливающими ценой одной копии
за тысячу американских денег.
По происхождению Maxima принадлежит к древнейшему роду среди
программ этого вида деятельности – она обладает, пожалуй, одной
из длиннейших историй среди всех сколь-нибудь распространённых
сегодня программ. Жизнеописание Максимы берёт своё начало в 60-х
годах, когда появился продукт под названием Macsyma, в котором
реализовывались, как принято сейчас говорить, «передовые идеи» в
области компьютерной математики. Позже эти идеи легли в основу обоих
уже упомянутых лидеров проприетарного рынка математического
софта – Mathematica и Maple.
Проект Macsyma был основан Энергетическим Управлением США
(Departament of Energy, DOE) в 60-х годах. Разрабатывать его начали
в легендарном Массачусетском Технологическом Институте (Massachusets
Institute of Technology, MIT), на языке, который заслуженно считался
тогда наиболее подходящим для невычислительных задач из всех
существовавших на тот момент. Этим языком был Lisp, единственный из
языков того времени доживший до наших дней и даже сейчас
соперничающий по распространённости в живых проектах со многими
ультрасовременными языками.
Естественно, изначально Macsyma была закрытым коммерческим
проектом. Доступность проекта OpenSource-сообществу стала возможной
благодаря профессору Техасского Университета Вильяму Шелтеру
(William Schelter), который добился от DOE получения кода Macsyma и
его публикации под лицензией GPL под именем Maxima. Он же долгое
время разрабатывал как саму Максиму, так и один из диалектов
лиспа – GCL (GNU Common Lisp) – на котором разрабатывалась
Максима после её «освобождения». К величайшему сожалению, Вильям
Шелтер умер в 2001 году. Но, как это часто бывает в мире открытого
ПО, жизнь проекта не закончилась вместе с жизнью его основателя.
Сейчас над проектом работает большое число математиков и
программистов во главе с Джеймсом Эмундсоном (James Amundson).
Теперь Maxima работает не только с GCL, но и с CLisp и CMUCL,
полностью отвечающими стандарту ANSI Common Lisp (в отличие от GCL,
в котором пока есть незначительные отклонения от стандарта).
В Максиме сейчас принят такой же принцип нумерации версий, как и
в ядре Linux: номер состоит из трёх чисел, разделённых точками,
причём номера с нечётным средним числом соответствуют так называемым
development-версиям (разрабатываемым), с чётным – stable
(стабильным). Стабильность одной ветки и статус «в разработке»
другой здесь означает не столько стабильность или нестабильность
работы программы, сколько стабилизацию самого процесса разработки: в
development-ветке новая младшая версия может иметь новые функции и
новые интерфейсы, в стабильной же младшие версии будут содержать
только исправления ошибок. Конечно, из этого следует несколько
больший риск столкновения с ошибками в разрабатываемой версии, но
риск этот весьма мал и в достаточной степени будет окупаться теми
нововведениями, которые изначально в стабильной версии будут
недоступны.
Версия, которая существует на момент выхода книги – 5.9.0, и
работа в основном ведётся над зачисткой кода для выпуска ветки 6.0.
Должен сказать в подтверждение своих слов о стабильности, что в
процессе работы с текущей версией я ни разу не столкнулся ни с одной
ошибкой.
1.2 Начинаем работу.
1.2.1 Различные интерфейсы.
Минимум, что вам нужно для того, чтобы начать работу с Максимой в
любом распространённом Linux-дистрибутиве, – это пакет maxima.
Для Debian и Alt Linux Master он входит в состав дистрибутива, для
RedHat/Fedora и Mandrake вы можете взять пакет на сайте проекта http://maxima.sourceforge.net/
(конечно, вы можете, как для каждого из упомянутых дистрибутивов,
так и для любого другого, собрать Максиму из исходников, лежащих на
том же сайте; я на этом останавливаться не буду). Этот пакет
содержит действительно минимум: консольную версию программы с
необходимыми библиотеками, man-страницу и несколько демо-файлов.
Консольная версия, конечно же, довольно-таки бедна визуальными
возможностями: все математические формулы «рисуются» обычными
текстовыми символами в несколько строк дисплея, а построения
графиков в иксах отображают свои результаты в отдельном окне (причём
продолжение работы возможно только после его закрытия), а в голой
консоли, естественно, вообще не работают. Но за счёт этого резко
понижаются требования к железу – Максима в консольном варианте
способна работать даже на таких компьютерах, которые сегодня и за
компьютеры никто не считает.
Помимо умолчательного текстового существуют несколько графических
интерфейсов к Максиме. Самостоятельная оболочка, xmaxima, написанная
на tcl/tk и не намного более требовательная к ресурсам, чем
консольный интерфейс, оснащена системой меню и позволяет встраивать
графические объекты прямо в документ в момент их создания (по
желанию пользователя), но математические знаки имитируются в ней,
также как и в консольной версии, текстовыми символами.
Ещё два интерфейса, emaxima и imaxima, реализованы как библиотеки
к редактору emacs. Первый из них пригодится тем, кто набирает свои
работы в формате LaTeX – это набор функций для LaTeX-режима
emacs, которые позволяют вставлять в документ Maxima-объекты и
вычислять их там же, вызывая Максиму автоматически и вставляя
результаты вычисления в виде LaTeX-выражений. Второй (imaxima)
превращает буфер редактора в подобие консольной Максимы, с той
разницей, что вывод генерируется также в виде LaTeX-объектов; только
отображаются они не в виде выражений исходника LaTeX, а так же, как
в уже откомпилированном dvi-документе, то есть математические
формулы рисуются привычными графическими обозначениями.
Четвёртый, и последний, графический интерфейс к Максиме –
это интерфейс к редактору TeXmacs, который основан на emacs'е, но
предназначен для визуального редактирования LaTeX-подобных
документов. В нём мы имеем дело не с LaTeX-искодником, а с самим
«внешним видом» документа, с текстом, оформленным и выглядящим точно
таким же, каким он будет при печати. Другими словами, речь идёт о
так называемом интерфейсе WYSIWYG (What You See Is What You
Get) – «видишь то, что получишь» – понятии знакомом многим
по таким программам как MS Word или OpenOffice. Но, в отличие от
двух помянутых, широкопрофильных и претендующих на универсальность,
TeXmacs создаётся в первую очередь для работы с текстами научной
тематики. В том числе TeXmacs имеет специальный математический режим
ввода, очень удобный для визуального ввода и редактирования формул.
Плюс с точки зрения пользователя Максимы здесь в том, что можно не
только получать вывод программы в привычной математической нотации,
но и использовать элементы такой нотации при вводе. Второй
плюс – возможность оперировать с формулами (как набранными
вами, так и теми, которые выводит Максима как результаты расчётов и
преобразований) как с обычными текстовыми объектами, например,
копировать их из буфера с интерфейсом Максимы в соседний буфер, в
котором вы набираете или правите любой текст.
Как видите, выбор достаточно богат, каждый сможет найти что-то по
своим вкусам, потребностям и аппаратным возможностям. Например, эта
книга пишется в редакторе TeXmacs с активным использованием
описанных выше плюсов во взаимодействии с Максимой. В этой связи я
буду использовать в примерах вышеназванную математическую нотацию (в
первую очередь для повышения читабельности книги), а при
необходимости по ходу объяснять, как всё то же самое записать в
строчку.
1.2.2 Средства общения с Maxima.
Работа в любом из пяти различных интерфейсов Максимы идёт в
диалоговом режиме. После запуска сессии Максимы мы видим нечто
такое:
GCL (GNU Common Lisp) 2.6.2 CLtL1 Jun 29 2004 18:53:13
Source License: LGPL(gcl,gmp), GPL(unexec,bfd)
Binary License: GPL due to GPL'ed components: (READLINE BFD UNEXEC)
Modifications of this banner must retain notice of a compatible license
Dedicated to the memory of W. Schelter
Use (help) to get some basic information on how to use GCL.
Maxima restarted.
(C1)
Символы «(C1)» перед курсором – это приглашение к вводу
первой команды. Команда в Максиме – это любая комбинация
математических выражений и встроенных функций, завершённая, в
простейшем случае, точкой с запятой. После ввода команды и нажатия
<Enter> Максима выведет результат и будет ожидать следующей
команды:
Можно вместо точки с запятой завершить команду знаком доллара
«$» – вывод этой команды будет заглушён, то есть, команда будет
обработана и результат будет вычислен, но не выведен на экран.
Для арифметических действий можно использовать традиционные
обозначения: «+», «–», «*», «/» и «**» или «^» для возведения в
степень. Например, ту же ячейку C1 можно записать так:
(C1) (1/2+1/3+1/4)/(1/5+1/6+1/8);
Как видите, в начале каждой строки стоит некое обозначение ячейки
этой строки. Каждая команда в Максиме обозначается через «C» с
номером («C» от «command»), каждая строка вывода – через «D» с
соответствующим номером («D» от «display»). При вводе мы можем
обращаться к любой из предыдущих ячеек по её имени, подставляя его в
любые выражения (перед именем ячейки ввода нужно при этом поставить
два апострофа). Кроме того, последняя ячейка вывода обозначена для
краткости и удобства через «%»:
В данном случае – это то же самое, что и . Это обозначение позволяет обращаться к последнему
результату, не отвлекаясь на то, каков его номер.
Естественно, мы можем не только использовать имена ячеек, но и
сами давать имена любым выражениям. По другому можно сказать, что мы
присваиваем значения переменным, с той разницей, что в виде значения
такой переменной может выступать любое математическое выражение.
Делается это с помощью двоеточия – знак равенства оставлен
уравнениям, которые, учитывая общий математический контекст записи,
проще и привычнее так читаются. И к тому же, так как основной конёк
Максимы – символьная запись и аналитические вычисления,
уравнения достаточно часто используются. Например:
В каком-то смысле двоеточие даже нагляднее в таком контексте, чем
знак равенства: это можно понимать так, что мы задаём некое
обозначение, а затем через двоеточие расшифровываем, что именно это
обозначение обозначает.
В последнем примере мы воспользовались встроенной функцией –
solve. Таких встроенных функций в Максиме очень много,
через них реализовано почти всё, что воспринимается как действия над
некими объектами. Так, в данном случае объект – это уравнение,
а действие – поиск решений этого уравнения.
Хочу сразу обратить внимание на одну особенность синтаксиса
Максимы, касающуюся имён. Пользовательские имена в Максиме
чувствительны к регистру, то есть прописные и строчные буквы в них
различаются. Это не будет в новинку тем, кто уже имел дело с
POSIX-совместимыми системами или с такими языками программирования,
как, скажем, Си или Перл. Удобно это и с точки зрения математика,
для которого тоже привычно, что заглавными и строчными буквами могут
обозначаться разные объекты (например, множества и их элементы,
соответственно). Особенность, о которой я сказал в начале абзаца, в
том, что это различие между большими и малыми буквами не
распространяется на имена встроенных функций. Это сложилось
исторически: первые версии Максимы не делали различий между
регистром букв (наверное, потому, что нет этого различия и в GNU
Common Lisp, на котором Максима написана); в последующих же версиях
эта особенность была оставлена для совместимости с кодом, написанным
для более ранних версий.
Естественно, после того, как выражение поименовано, мы можем где
угодно звать его по имени:
Как нетрудно догадаться, diff – это функция
дифференцирования.
Иногда может быть нужно не выполнить некую функцию, а
использовать её в своём математическом контексте. Например, уже
упомянутая функция дифференцирования может пригодиться нам для
обозначения производной в дифференциальном уравнении; в этом случае,
конечно, вычислять её не надо. Для таких нужд используется знак
апострофа:
Обратите внимание, что, если вы работаете с Максимой в TeXmacs,
то апостроф нужно вводить не в математическом, а в текстовом
режиме – в математическом режиме ввода апостроф обозначает
производную.
Любое имя, имеющее значение, будь то имя ячейки C или D, или
любое другое, которому мы назначили выражение с помощью «:», можно
очистить с помощью функции kill. Ею же можно очистить
всю память разом, набрав «kill(all)»; после этого нумерация ячеек
вновь пойдёт с единицы. В дальнейшем, если по контексту будет
иметься ввиду логическое продолжение предыдущих строк ввода-вывода,
я буду продолжать нумерацию (этим приёмом я уже воспользовался
выше). Когда же новый «сеанс» будет никак не связан с предыдущим,
буду начинать нумеровать заново; это будет косвенное указание
сделать «kill(all)», если вы будете набирать примеры в максиме, так
как имена переменных и ячеек в таких «сеансах» могут
повторяться.
1.2.3 Основные принципы работы.
Уже в начале работы с Максимой мне, даже если бы я ещё не знал
этого, стало понятно, что она написана на Лиспе. Действительно, в
Максиме чётко прослеживается лисповский принцип работы с данными,
который, кстати, оказывается действительно очень удобным в контексте
символьной математики и аналитических вычислений. Дело в том, что в
Лиспе (а соответственно, и в Максиме), по большому счёту нет
разделения на объекты и данные: имена переменных и выражения могут
использоваться практически в одном и том же контексте. В Максиме же
это свойство доведено буквально до максимума: когда мы используем
любой символ в выражении он может трактоваться и просто как символ,
и как имя, данное какому-либо выражению. По умолчанию, без
дополнительных синтаксических ухищрений (о которых ниже), символ,
связанный с любым выражением, будет представлять это выражение;
символ, не связанный ни с чем, будет представлять самого себя
(трактуемого опять-таки как выражение). Простенький пример:
Из этого следует, в частности, что вместо любого символа в
содержащее его выражение автоматически подставляется его значение
только в том случае, если это значение было ему приписано до
определения выражения.
Тут есть ещё один момент, на котором стоит остановиться. Обратите
внимание на номера ячеек с C1 по D6. Как видите, при заглушении
вывода мы получаем ячейку ввода, которой с виду не соответствует ни
одна ячейка вывода; на самом деле эта ячейка (D2) сохранена в памяти
и доступна под этим именем (вы можете это проверить, набрав «D2;»),
но просто не выводится на экран. С ячейкой D5 на самом деле
произошло то же самое: просто в строке, помеченной как C5 мы в
действительности ввели две ячейки ввода, C5 и C6, несмотря на то,
что номер отобразился один; а ячейка D5, точно так же, как D2,
просто не отобразилась. Мы также можем проверить это, обратившись,
скажем, к ячейке C6 через «' 'C6;».
Если мы уже имеем символ с каким-то значением и хотим
использовать в выражении сам этот символ, а не его значение, мы
можем оградить этот символ от вычисления точно так же, как это уже
было показано для встроенной функции:
Результат выражения C8 был бы аналогичен и в том случае, если бы
b не имело никакого значения; таким образом, мы можем
смело блокировать вычисление символа, даже если точно не знаем,
может ли он быть вычислен вообще.
В противовес блокировке вычислений, мы можем и вычислить любое
выражение принудительно: такое принуждение будет означать, что
вычислится не только само выражение, но и все входящие в него
символы. Такое принудительное вычисление делается с помощью функции
ev:
Кстати, при вызове ячейки ввода с помощью двух апострофов эта
ячейка автоматически будет вычислена. Изюминка вычисления через ev в
том, что будут вычислены все символы входящие в выражение,
независимо от того, блокировалось ли их вычисление при определении
выражения, или сами эти символы на тот момент ещё ничего не
определяли:
Каждое применение ev вычисляет выражение только на один уровень в
глубину, но мы можем применять его к любому выражению сколько угодно
раз:
Вообще, ev – едва ли не самая мощная функция в
Максиме; с помощью дополнительных параметров, которые могут быть
переданы ей в списке любой длины после вычисляемого выражения, можно
очень гибко управлять его вычислением. Пытаться пересказать эти
возможности в двух словах не хочется, поэтому на функции ev мы позже
остановимся более подробно.