Глава 9. Система компьютерной алгебры Mathematica 4
 
 
 
 

Mathematica 4 — мировой лидер среди СКМ. В этой системе существенно повышена скорость численных вычислений и введена технология эффективной упаковки массивов. В сочетании с удобным пользовательским интерфейсом, мощными возможностями символьной математики и превосходной графикой система находит самое широкое применение в науке, технике и образовании.

 

Интерфейс пользователя

При запуске системы Mathematica 4 можно наблюдать появление элементов интерфейса системы прямо на рабочем столе Windows 95/98/NT (рис. 9.1). Интерфейс определяется одной из двух основных частей системы — интерфейсным процессором Front-end (вторая основная часть представляет собой ядро системы Kernel). После загрузки интерфейсного процессора появляется строка меню системы, палитра ввода и пустое окно редактирования документов (даже без курсора ввода). В нем можно начинать вычисления, что и иллюстрирует рис. 9.1. В последней строке документа показан шаблон ввода определенного интеграла, введенного с помощью палитры ввода.

 

Рис. 9.1. Вид запущенной системы Mathematica на рабочем столе Windows 98


Для выполнения простых вычислений достаточно набрать в строке ввода необходимое математическое выражение и нажать клавиши
Shift+Enter (клавиша Enter задает перевод строк). Результат появится в строке вывода. В Mathematica необычна форма задания функций — они начинаются с большой буквы, а аргументы Функций задаются в квадратных скобках, например Sin[1], а не sin(1). Круглые скобки используются для задания приоритета вычислений в сложных выражениях. Десятичная точка делает число вещественным, а особая функция N[expr] или N[expr,n] вычисляет выражение ехрr в виде вещественного десятичного числа с плавающей точкой и n знаками после этой точки.

 

Строка меню и окно редактирования документов

Строка меню Mathematica 4 имеет следующие характерные позиции: Cell — работа с ячейками (их объединение и разъединение, установка статуса, открытие и закрытие); Format — установка форматов документов (шрифты, стили, размеры, фон, цвета и т. д.); Input — задание элементов ввода (графиков, матриц, гиперссылок и др.); Kernel — управление ядром системы и свойствами ячеек; Find — поиск заданных данных об объектах.

Палитры спецзнаков (рис. 9.2) выводятся с помощью команд подменю Palettes меню File.

 

Рис. 9.2. Палитры спецзнаков системы Mathematica 4


Для форматирования документа используются команды меню
Format. Для ввода математического выражения по шаблону и для представления его в естественной математической форме используется стандартный формат ячеек ввода. Преобразование форматов ячеек выполняется командами меню Cell. На рис. 9.3 показан созданный простой документ.

 

Рис. 9.3. Простой документ


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

В новых версиях Mathematica 3/4 команды для установки стиля интерфейса находятся в меню Format: Show Ruller — отображение линейки; Show ToolBar — отображение панели инструментов; Show Page Break — отображение линии разрыва страницы; Magnitification — задание (в процентах) масштаба отображения элементов документа.

 

Новинки системы Mathematica 4

В системе Mathematica 4 кардинально повышена скорость численных расчетов (рис. 9.4).

 

Рис. 9.4. Сравнительные данные по скорости простых вычислений


Скорость возросла в 5-10 раз, а для матричных операций и того выше (до 200 раз для поиска минимального и максимального по значению элемента списка). В несколько раз уменьшено время обращения к памяти при записи и считывании массивов, а заодно существенно повышена плотность упаковки массивов. Появилась возможность вращения мышью графиков трехмерных фигур.

Эта возможность достигнута за счет существенного ускорения построения сложных трехмерных фигур и реализуется с помощью команды << RealTime3D'. Другая команда << Default3D' возвращает систему к стандартным возможностям построения трехмерной графики.

 

Файловая система и пакеты расширений

Документы системы представлены файлами текстового формата и имеют расширение .nb. Сохранение и считывание файлов осуществляется обычным способом — помощью команд меню File. Система имеет ряд пакетов расширения (AddOns) системы, которые хранятся в папке ADDONS:

• Algebra — работа с полиномами, алгебраическими неравенствами, гамильтоновой алгеброй и др.;

• Calculus — типовые операции математического анализа;

• DiscreteMath — вычисления из области дискретной математики;

• Geometry — функции для выполнения геометрических расчетов на плоскости и в пространстве;

• Graphics — дополнительные возможности графики;

• LinearAlgebra — решение задач линейной алгебры;

• Miscellaneus — всякая всячина;

• NumberTheory — функции теории чисел;

• NumericalMath — расширенные реализации важнейших численных методов;

• Statistics — статистические функции;

• Utilities — дополнительные утилиты.

Кроме обычных команд (см. главу 5) в меню File имеется ряд специфических:

• Save As Special — запись в специальных форматах;

• Open Special — открытие файлов в специальных форматах;

• Open Selection — открытие выделенных файлов;

• Import — импорт файлов (аналогична команде Open);

• Send To и Send Selection — зарезервированы;

• Palettes — вывод палитр математических спецзнаков, операторов и функций (см. выше);

• Notebook — вывод списка документов, которые загружались ранее;

• Generate Palette from Selection — преобразует выделенные ячейки документа в палитру;

• Generate Notebook from Palette — преобразует палитру в документ со своим именем;

• Print Selection — печать выделенных ячеек.

 

Редактирование документа

Помимо обычных средств редактирования (команд меню Edit) документов в Mathematica предусмотрены обширные возможности по изменению стиля документов и их частей — команды меню Format.

Стилем ячеек называют именованную совокупность параметров форматирования ячеек. Команды для назначения стиля собраны в подменю Style меню Format. Это команды ScreenStyleEnvironment — изменение текущего формата отображения ячеек документа на экране и PrintStyleEnvironment — изменение текущего формата ячеек документа при печати. Доступны следующие параметры: Working — рабочий стиль (типичный); Presetnation — презентация (увеличенные размеры символов); Condesed — сжатый (уменьшенный размер символов); Printout — принтерный (оптимальный при печати). Команда ShowExpression служит для управления отображением выражений в стандартном и развернутом видах (со всеми директивами и параметрами). Команда RemoveOptions удаляет все введенные пользователем настройки и восстанавливает исходное состояние системы.

Обычно редактирование документов начинают с форматирования текстовых ячеек. Оно подобно описанному для офисных программ. Далее можно выбрать стиль оформления ячейки. Ряд команд преобразования стилей сосредоточен в меню Cell. В меню Edit имеется ряд специальных позиций:

• Clear Del — удаление выделенной ячейки;

• Paste and Discard — вставка из буфера с очисткой последнего;

• Save Selection As — запись выделенных ячеек в специальных форматах;

• Select All — выделение всех ячеек;

• Insert Object — вставка объектов;

• Motion — различные перемещения в текстовом блоке;

• Expression Input — ввод выражений в разных форматах;

• Make 2D — создание входных выражений в двухмерном формате;

• Check Balance — включение проверки баланса;

• Preferences — вызов диалогового окна параметров.

Команды подменю Save Selection As (рис. 9.5) служат для записи выделенных ячеек в специальных форматах.

 

Рис. 9.5. Подменю Save Selection As


Команда
Insert Object открывает стандартное диалоговое окно вставки объектов. В окне есть перечень приложений, экспортирующих в Mathematica порожденные ими объекты.

 

Ячейки

Ячейки (cells) являются основными объектами документов. Ячейки отличаются их статусом, то есть совокупностью свойств, определяющих поведение ячейки в различных ситуациях. Статус можно распознать по ряду признаков, например виду указателя мыши в области ячеек. Другой признак — опознавательный знак в верхней части квадратной скобки, обрамляющей ячейку. Отсутствие знака означает, что это обычная ячейка ввода.

В меню Cell имеются команды для работы с ячейками: преобразования и изменения формата, группировки, объединения и разделения ячеек. Команды подменю Cell Properties служат для установки свойств — статуса ячеек. Это команды Cell Open, Cell Editable, Cell Edit Dublicate, Cell Evaluatable, Cell Active и Initialization Cell, которые описаны ниже.

Ячейка ввода и соответствующая ей ячейка вывода обрамляются не только своими удлиненными квадратными скобками справа, но и общей скобкой. Активизируя эту скобку двойным щелчком, можно скрывать или выводить на экран выходную ячейку. Скрывать последнюю полезно, если содержащийся в ней результат слишком громоздок. Можно форматировать не только входные, но и выходные ячейки, например, вручную задавая более приемлемый вид результата. Однако для этого надо выходную ячейку сделать редактируемой (команда CellEditable). Редактируемая ячейка имеет символ ´ у своей обрамляющей скобки.

Ячейки могут быть исполняемыми или нет, что задается командой Cell Evaluatable. Только исполняемые ячейки обрабатываются ядром системы и порождают результат. Такие ячейки помечаются знаком - в обрамляющей их правой скобке. Исполнение начинается, как только происходит оценка статуса какой-либо ячейки.

Ячейки также могут быть активными и неактивными. Изменение активности достигается командой Cell Active. Активная ячейка помечается в скобке знаком А и обычно управляется кнопкой. Наконец, ячейки могут быть инициализированными или нет (команда Initialization Cell). Инициализированная ячейка помечается в скобке знаком | и автоматически исполняется при загрузке документа, содержащего такую ячейку (или ряд ячеек).

Команда Group Cells используется для объединения ряда ячеек в одну группу. Группу можно раскрывать и сжимать, активизируя ее общую квадратную скобку. Команда Ungroup Cells разъединяет объединенные в группу ячейки. Для деления ячейки на части используется команда Divide Cell, а для объединения двух ячеек — команда Merge Cells. Команда Open All Subgroups открывает все подгруппы, а команда Close All Subgroups закрывает все выделенные группы и подгруппы ячеек. Это позволяет создавать электронные документы.

 

Графика

Система Mathematica обладает превосходными графическими возможностями и имеет для этого множество функций. Например, графическая функция Plot[{f1[x], f2[x],...}, {х, xmin, хmах}] строит графики произвольных математических функций f1[х], f2[х], ... одной переменной х при ее изменении от минимального значения xmin до максимального хmах (рис. 9.6). Другая графическая функция Plot3D[f[x,y], {{х,xmin,xmax}, {y,ymin,ymax}}] строит график трехмерной поверхности для математической функции f [х,у] двух переменных, изменяющихся в указанных пределах. Он также показан на рис. 9.6 вместе с его контекстным меню.

 

Рис. 9.6. Построение двухмерных и трехмерных графиков функций


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

В меню Cell имеется ряд команд, относящихся только к ячейкам вывода с графическими и звуковыми объектами (в версиях Mathematica 3.0 и ниже они находились в меню Graph): Animate Selected Graphics — анимация выделенной ячейки с графиком; Play Sound — воспроизведение синтезированного звука; Rerender Graphics — перерисовка графиков; Rerender And Save Graphics — перерисовка графиков и их запись; Make Standard Size — установка стандартного размера ячейки; Allign Selected Graphics — объединение выделенных графиков; Cell Size Statistics — вывод статистики о размерах ячеек.

Команда Get Graphics Coordinates выводит окно координат двухмерных графиков. Для получения координат двухмерных графиков прежде всего их надо выделить, а затем, удерживая клавишу Ctrl, поместить указатель мыши на нужной точке графика. При этом в левой нижней части окна появится список с координатами точки (координаты x и y в фигурных скобках). Затем следует воспользоваться командой Сору для переноса координат точек в буфер обмена для последующего использования.

Многие параметры документов задаются по умолчанию. В Mathematica 4 имеется специальный инспектор параметров (рис. 9.7), который можно запустить командой Option Inspector меню Format или контекстного меню (см. рис. 9.6).

 

Рис. 9.7. Инспектор параметров


С помощью, окна инспектора параметров можно изменять параметры, заданные по умолчанию. В качестве примера на рис. 9.7 показана подготовка к смене шрифта. Другой путь изменения параметров — задание их в функции — будет рассмотрен позже. Параметры существенно влияют на вид документов.

Команда 3D View Point Selector служит для вывода окна настройки трехмерных графиков (рис. 9.8). Это окно можно открыть при наличии в документе трехмерного графика и установке в строку ввода с графической функцией курсора ввода.

 

Рис. 9.8. Окно настройки трехмерных графиков


В этом окне имеется изображение куба в пространстве, который можно вращать с помощью мыши или перемещением бегунков на полосах прокрутки, задающих параметры просмотра и перспективы объекта (увы, сам объект при этом не виден). Щелчок на кнопке
Paste создает строку ViewPoint[{x,у,z}], которая помещается на место курсора ввода в окне редактирования документа. В данном случае курсор ввода надо расположить в строке функции Plot3D после запятой следом за списком параметров. Если теперь исполнить модифицированную функцию, то рисунок будет перестроен (рис. 9.9).

 

Рис. 9.9. Пример разворота трехмерной фигуры


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

 

Звук

Команда Record Sound выводит окно Фонографа, входящего в состав операционной системы Windows 95/98 (рис. 9.10) и позволяющего записывать и воспроизводить звуки.

 

Рис. 9.10. Фонограф для записи и воспроизведения звука


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

 

Ввод элементов документа

В этом разделе мы рассмотрим команды меню Input. В документ могут быть вставлены различные объекты, хранящиеся в файлах различных форматов, например текстовых или графических. Команда Get File Path открывает окно загрузки таких файлов.

Создание таблиц и матриц в системе Mathematica легко выполняется с помощью соответствующих функций. Однако команда Create Table/Matrix/Palette обеспечивает такую возможность и с помощью меню. Она выводит окно задания таблиц матриц и палитр, показанное на рис. 9.11 справа.

 

Рис. 9.11. Работа с окном Create Table/Matrix/Palette


В левой части документа показаны примеры работы с данным окном. Оно выводит палитру матриц — по умолчанию из трех строк и трех столбцов.

При подготовке сложных документов с диалоговым режимом иногда полезно создание кнопок. Оно реализуется с помощью команд подменю Create Button, которые представляют собой имена типов кнопок. Например, кнопка типа Evaluate Cell служит для создания исполняющей вычисления ячейки. Она выглядит как прямоугольник. Редактирование кнопок осуществляется по команде EditButton.

Гиперссылка является объектом в виде подчеркнутой текстовой надписи, связанной с некоторым другим объектом, представленным файлом, например, какого-либо документа или рисунка. При активизации гиперссылки мышью связанный с ней объект загружается. Для создания гиперссылки выделяется какое-либо слово (или фраза), а затем выбирается команда Create Hyperlink. Открывается окно, показанное на рис. 9.12 в правой части экрана.

 

Рис. 9.12. Создание гиперссылки


Следующий этап заключается в установке связи гиперссылки с нужным файлом. Его полное имя можно прямо указать в верхнем поле над кнопкой
Browse. Этой кнопкой можно воспользоваться для поиска файла. После этого выделенное слово (фраза) превратится в гипертекстовую ссылку.

Для вставки содержимого предшествующих ячеек ввода и вывода служат команды Copy Input from Above и Copy Output from Above. Поясним это примерами. Введем в ячейку ввода выражение 1+2. Нажав клавиши Shift+Enter, получим строку вывода — 3. Теперь, выбрав команду Copy Input from Above, получим новую строку ввода — 1+2. Ее исполнение даст 3. Последующий выбор команды Copy Output from Above тоже даст 3. Еще одна команда Start New Cell Bellow служит для вставки новых пустых ячеек ввода между уже имеющимися. Ячейка вставляется ниже курсора ввода, указывающего место вставки.

Запомнить около тысячи функций, входящих в ядро систем Mathematica, довольно сложно, так же как и правила их записи. Для облегчения ввода служат две заключительные команды меню Input. Первая из них доступна, если курсор находится на каком-либо ключевом слове в строке ввода. Тогда выбор команды Complete Selection выводит список имен всех функций, которые содержат данное слово. Рис. 9.13 поясняет это на примере ввода слова Plot.

 

Рис. 9.13. Пример исполнения команды Complete Selection


Соответственно, команда
Make Template в указанной курсором функции выдаст список ее параметров. Например, если введено слово Plot и курсор ввода расположен следом за ним, команда Make Template приведет к следующему изменению строки ввода: Plot [f, x, xmin, xmax]. После этого становится ясно, как записывается эта функция и какие параметры требуется ввести.

 

Ядро системы

Команды меню Cernel служат для управления действиями ядра системы, проводимыми над ячейками загруженного документа. Здесь есть также команды ввода субсекции Enter Subsection и удаления субсекции Exit Subsection. Часто используются команды Interrupt — прерывание вычислений и Abort — полное прекращение вычислений.

В Mathematica предусмотрена команда Show In/Out Number, управляющая отображением или скрытием сообщений с номерами строк In[n] и Out[n]. Для отображения или скрытия всех ячеек вывода служит команда Delete All Output.

В меню Find представлены команды поиска и замены фрагментов текстов и выражений.

Особым признаком ячеек ввода могут быть их комментарии (tags) — короткие сообщения, характеризующие суть выполняемых в ячейках действий и размещаемые над строкой ввода. Признаком наличия у данного документа комментариев является их список, который появляется в подменю Cell Tags меню Find. Команда Add/Remove Cell Tags позволяет добавить комментарий в строку ввода, если его нет, или удалить комментарий из строки, если он есть. Эта команда вызывает появление окна редактирования комментариев. Работа с этим окном вполне очевидна — кнопка Add добавляет комментарий, а кнопка Remove удаляет. Команда Cell Tag from In/Out Name позволяет добавить в список комментариев заголовок выделенной строки ввода или вывода.

Последняя команда меню Find — Make Index — помещает в буфер обмена все комментарии текущего документа. Она выводит окно, в котором можно указать признаки комментариев. Щелчок на кнопке ОК помещает список этикеток в буфер обмена, откуда его можно извлечь с помощью команды Paste.

 

Справочная система

Mathematica 4 имеет прекрасно исполненную справочную базу данных (рис. 9.14). Команды доступа к ней, как обычно, сосредоточены в меню Help.

 

Рис. 9.14. Окно справочной системы Mathematica


В окне справочной системы можно установить следующие разделы справок:
Built-in Functions — встроенные функции; Add-ons — пакеты расширений; The Mathematica Book — математический справочник; Getting Started/Demos — начало работы и демонстрации; Other Information — другая информация; Master Index — справка по индексу (алфавитный каталог).

Практически по каждой функции приведен ряд примеров, которые открываются при активизации гиперссылки в виде треугольника с надписью Further Examples. Примеры являются “живыми” в том смысле, что, не выходя из справочной системы, можно, выделив ячейку, получить новый результат. Можно также, выделив ячейки примеров, перенести их содержание в буфер обмена командой Сору и затем разместить в текущем документе командой Paste. Такой пример можно редактировать и использовать для решения своих задач.

В меню Help имеется еще ряд команд: Registration — вывод формы регистрации; Find in Help — поиск нужных разделов в справочной системе; Why the Beep? — зарезервирована под выдачу информации о звуковых возможностях; About Mathematica — вывод окна с краткими данными о системе и фирме Wolfram; Rebuild Help Index — создание индексного указателя. Действие этих команд вполне очевидно.

 

Средства обычных вычислений

 

Вычисления с целыми и вещественными числами

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

При работе с целочисленными данными Mathematica 4 обеспечивает точные вычисления:

123456789123456789123456789^2
15241578780673678546105778281054720515622620750190521
%/123456789123456789123456789
123456789123456789123456789

Знак % означает использование последнего результата вычислений. Для вычисления чисел с произвольным основанием используется конструкция Основание^^Число:

16^^123abcde
305839326
2^^1010111
87

Функция BaseForm[expr, n] возвращает выражение ехрr в форме числа с основанием n (до 32), которое указывается как подстрочный индекс:

BaseForm[87, 2]
10101112
BaseForm[305839326,16]
123abcde16

Для представления выражения ехрr в форме вещественного числа используется функция N[expr] или N[expr, числo_цифр_результата]. Пример:

N[2*Pi,50]
6.283185307179586476925286766559005768394338

Mathematica имеет две системные переменные, позволяющие вывести максимально и минимально возможные значения чисел, с которыми оперирует система:

$MaxMachineNumber
1.79769´10308
$MinMachineNumber
2.22597´10-308

Функции IntegerPart[x] и FractionalPart[x] обеспечивают возврат целой и дробной частей вещественного числа х, а функция RealDigits[x] возвращает список реальных цифр результата и число цифр целой части х. Есть множество и других функций для работы с числами.

 

Символьные данные, строки и выражения

Символьные строки задаются цепочкой символов в кавычках, например "sssss". В них могут использоваться следующие управляющие символы для строчных объектов: \n — новая строка, \t — табуляция. Это иллюстрируется следующими примерами:

"Hello\nmy\nfriend!"
Hello
my
friend!
"Hello\tmy\tfriend!"
Hello my friend!

Выражения в системе Mathematica обычно ассоциируются с математическими формулами, например (слева запись на языке Mathematica, справа — обычная математическая запись):

2*Sin[x]                       2•sin(x)
2 Sin[x]                       2sin(x)
(a + b^2 + c^3)/(3*d - 4*e)    (a+b2+c3)/(3d-4e)
Sqrt(2)                        
Integrate[Sin[x],x]            

Отметим некоторые тонкости синтаксиса языка общения системы. Знак умножения может быть заменен пробелом. Встроенные функции начинаются с прописной буквы и обычно повторяют свое общепринятое математическое обозначение. Некоторые греческие буквы воспроизводятся латинскими буквами, соответствующими им по звучанию. Круглые скобки (...) используются для выделения частей выражений и задания приоритета их выполнения. Параметры функций задаются в квадратных скобках [...]. Фигурные скобки используются при задании списков {...}.

 

Списки, массивы и объекты

Наиболее общим типом сложных данных в системе являются списки (lists). Они, как и векторы, и матрицы, задаются следующим образом:

• {1, 2, 3} — список из трех целых чисел;

• {а, b, с} — список из трех символьных данных;

• {1, а, х^2} — список из разнотипных данных;

• {{a,b},{c,d}} — список, эквивалентный матрице;

• ^2+у^2, 2*Sin[x]} — список из двух математических выражений.

В общем случае система Mathematica оперирует с объектами, имена (идентификаторы) которых строятся по следующим правилам: sssss — имя объекта, заданнoro пользователем; Sssss — имя объекта, входящего в ядро системы; $Sssss — имя системного объекта. Различные объекты системы будут более подробно описаны в дальнейшем по мере знакомства с системой. Полный список объектов, заданных в ядре системы, легко получить, используя команду ?*. Можно также получить список всех определений на заданную букву, используя команду ?S*, где — любая буква латинского алфавита. Аналогичные возможности представляет функция Name["S"], например, Names["A*"] выводит список всех ключевых слов начинающихся с символа А. Наконец, командой ?Name можно вывести справку по любому определению с именем Name, например, ?Sin выводит сообщение Sin[z] gives the sine of z. С помощью команды ?Name можно проверить, является ли имя объекта Name уникальным или оно уже использовано в системе.

 

Функции, ключи, атрибуты и директивы

К важному типу объектов принадлежат функции — объекты, имеющие имя и список параметров и возвращающие некоторое значение в ответ на обращение к ним по имени, с указанием в списке конкретных (фактических) значений параметров:

Идентификатор_функции[01, 02, 03, ...]

Здесь 01, 02, 03, ... — параметры, математические выражения и т. д. Список входных параметров задается необычно — в квадратных скобках.

В числе входных параметров могут быть специальные объекты — ключи. Они задаются в виде Имя_ключа->3начение_ключа. Значением ключа обычно является то или иное слово. Например, в функции построения графиков Plot[sin[x], {x,0,20}, Axes->None] параметр Axes->None указывает на то, что отменяется вывод координатных осей (Axes). Функция Options[name] выводит для функции с идентификатором name список всех возможных для нее ключей. Некоторые функции, например Sin, могут вообще не иметь ключей, другие, например Solve, могут иметь целый “букет” ключей.

Каждый объект может характеризоваться некоторой совокупностью своих свойств и признаков, называемых атрибутами. Функция Attributes[name] возвращает список всех атрибутов функции с именем name, например:

Attributes[Sin]
{Listable,NumericFunction,Protected}
Attributes[Solve]
{Protected}

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

 

Константы, размерные величины и переменные

В Mathematica 4 используются следующие именованные константы: Complex Infinity — комплексная бесконечность; Degree — число радиан в одном градусе, которое имеет числовое значение Pi/180; E — основание натурального логарифма c приближенным числовым значением 2,71828...; EulerGamma — постоянная Эйлера с числовым значением 0,577216...; GoldenRatio — константа со значением (1+Sqrt[5])/2, определяющая деление отрезка по правилу золотого сечения; I — представляет мнимую единицу Sqrt[-1]; Infinity — “положительная” бесконечность (со знаком минус — “отрицательная” бесконечность); Catalan — константа Каталана 0,915966...; Pi — число p . Имеющие значение константы хранят их в виде вещественных чисел:

{N[Degree], N[E], N[Pi]}
{0.0174533,2.71828,3.14159}
{N[EulerGamma],N[GoldenRatio],N[Catalan]}
{0,577216,1.61803,0.915966}

Mathematica позволяет оперировать с размерными величинами, которые широко используются для физических и химических расчетов. Например, 1 Meter или 0.5 Second.

Без особых на то указаний переменные в системе Mathematica являются глобальными. Ниже представлены основные операции по присваиванию переменным их значений:

• х = value — переменной х присваивается значение value;

• х = у = value — значение value присваивается переменным х и у;

• x:=value — отложенное присваивание переменной х значения value;

• х =. — с переменной х снимается определение.

Примеры:

• g = Plot[Sin[x], {х,0,20}] — переменной g присваивается значение в виде графического объекта;

• у = 1 + х^2 — переменной у присваивается символьное значение в виде выражения (1 + х^2);

• z = {1, 2, х, а + b} — переменной z присваивается значение в виде списка, содержащего четыре элемента.

Различие в присваивании переменным значений с помощью знаков = и := иллюстрируют следующие примеры: а=12 возвращает 12, b:=15 возвращает в разных строках b и 15.

Возможно снятие с переменной определения с помощью символа =. (знак равенства с точкой). Указанным операторам присваивания соответствуют функции обычного присваивания Set[lhs,rhs] и задержанного присваивания SetDelayed[lns,rhs]. Есть и другие редко используемые функции присваивания UpSet[lns,rhs] и UpSetDelayed[lhs,rhs]. Отметим еще одну важную конструкцию:

SetOptions[s, name1->value1, name2->value2, ...]

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

 

Подстановки и функции пользователя

Операции подстановки в Mathematica вводятся с помощью комбинированного символа /. (слеш с точкой): ехрr /. х -> value — в выражение ехрr вместо переменной х подставляется ее значение value; ехрr /. {х -> xvalue, у -> yvalue} — в выражение ехрr вместо переменных х и у подставляются их значения xvalue и yvalue. Примеры:

1+x^3/.x->1+z
1+(1+z)3
х^2+2*х+3/.х->2
11

В целом для операций подстановок (rule) используют следующие обозначения: lhs -> rhs — прямая подстановка lhs в rhs и lhs :> rhs — задержанная подстановка (ruledelayed), которая преобразует lhs в rhs, вычисляя rhs только в том случае, если используется правило подстановки:

р:=1+х^2+3*х^3
р/.х->1+у
1 + (1+у)2+3(1+у)3
f[1],f[2],f[3]/.f[n_]->n^2
{1, 4, 9}
f[n_]:=n^2
f[4]+f[y]+f[x+y]
16+у2+(х+у)2

Для задания, опознавания и удаления функций пользователя используются следующие конструкции:

• f(x_) := х^3 — отложенное задание функции пользователя с именем f;

• f(х_)= х^3 — немедленное задание функции пользователя с именем f;

• ?f — вывод информации о функции f;

• Clear[f] — уничтожение определения функции f.

В обозначениях вида х_ знак _ применяется для создания так называемых образцов, задающих локальные переменные в теле функции (в нашем примере это х^3). При этом в самом теле функции переменные обозначаются как обычно, без знака образца. Mathematica имеет ряд и других образцов (см. справочную систему). Mathematica позволяет записать введенные пользователем функции с их определениями на магнитный диск с помощью инструкции: Save["filename", f1, f2, ...]. После этого функция пользователя становится внешней функцией. При этом для ввода таких функций в текущий документ достаточно вызвать файл с именем filename: <<filename.

Рекомендуется создавать файлы с типовым расширением .m. Такие файлы входят в пакеты расширений системы. Имя файла нужно задавать по общепринятым для MSDOS правилам, то есть при необходимости указывать идентификатор логического диска и путь к файлу, например: <<D:\MAT\myfunc.m.

Функции пользователя можно задавать и выводить на печать как на языке системы, так и на некоторых общепринятых языках программирования, например Fortran, С или ТеХ. Для этого существует ряд функций преобразования, например CForm[expr], FortranForm[expr] и TeXForm[expr]. Для подсоединения созданных на этих языках программ, содержащих формулы и данные, в вывод системы Mathematica используются функции: Splice["file.mx"] — включает вывод системы во внешний файл и Splice["infile","outfile"] — включает вывод системы в файл infile и отправляет результат в файл outfile. Таким образом, система Mathematica может общаться с другими программами, написанными на тех или иных языках программирования.

 

Арифметические операторы и функции

Mathematica 4 помимо общепринятых арифметических операторов (+, -, *, / и ^) имеет оператор ехрr //N, который дает приближенное (с установленной точностью и формой) значение выражения ехрr. Полезно отметить, что знак пробела является арифметическим оператором умножения, если по обе стороны от него стоят операнды. Знак % возвращает результат последней предшествующей операции, а %% возвращает результат операции, выполняемой перед последней предшествующей операцией, и т. д.

Если х имеет вещественное значение, функция MantissaExponent[x] возвращает список, содержащий мантиссу и порядок приближенного вещественного числа х. Следующие две функции, Rationalize[x] и Rationalize[x,dx], дают приближение для числа х в виде рациональных чисел (вторая из этих функций задает приближение с заданной точностью):

Rationalize[N[Pi],10^-3]

Rationalize[N[Pi],10^-12]

Спецификой Mathematica являются арифметические операторы с укороченной

формой записи.

Функция

Оператор

Описание

Increnent[i]


Decrement[i]


PreIncrement[i]


PreDectement[i]


AddTo[x,d]


SubstractFrom[x,dx]


TimesBy[x,c]


DivideBy[x,c]

i++


i--


++i


--i


x += dx


x -= dx


x
*= с


x
/= с

Увеличивает значение i на 1 до использования i в выражении

Уменьшает значение i на 1 до использования i в выражении

Увеличивает значение i на 1 после использования i в выражении

Уменьшает значение i на 1 после использования i в выражении

Прибавляет dx к х и возвращает новое значение х

Отнимает dx от х и возвращает новое значение х

Умножает х на с и возвращает новое значение х

Делит х на с и возвращает новое значение х

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

Ввод

Вывод

i=0

++i; ++i; ++I

i=0; i++; i++; i++

--I

i--

i--

х=5

х+=0.5

х-=0.5

х*=2

х/=5

0

3

2

4

5

4

5

5.5

5.

10.

2.

В дальнейшем при такой форме представления примеров мы будем опускать указания на ячейки ввода (слева) и вывода (справа). Для выполнения арифметических действий в Mathematica 4 определены следующие арифметические функции:

• Divide[x, у] — возвращает результат деления х на у, что эквивалентно выражению х у^-1;

• Plus[x, у, ...] — возвращает сумму элементов списка;

• PowerMod[a, b, n] — возвращает Mod [a^b, n] (для b<0 возвращает инверсию остатка);

• Times[x, у, ...] — возвращает произведение аргументов х*у*...;

• Mod [m, n] — возвращает остаток от деления m на n.

Примеры на применение арифметических функций:

Divide[1.,3]
0.333333
Mod[123,20]
3
Mod[123,-20]
-17
Mod[-123,20]
17
Plus[2,3,4]
9
Times[2,3,4]
24

Для обмена значениями переменных х и у можно использовать выражение {х,у} =={у,х}. Следующие функции служат для приведения вещественных чисел к ближайшим целым по определенным правилам:

• Ceiling[x] — возвращает значение наименьшего целого числа, большего или равного х;

• Floor[x] — возвращает наибольшее целое число, не превышающее данного х;

• Quotient[n, m] — возвращает целое значение n/m, определяемое как Floor[n/m];

• Round[x] — округляет х до ближайшего целого.

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

Ceiling[{-.5.9,-5.1,5,5.1,5.9}]
{-5,-5,5,6,6}
Floor[{-.5.9,-5.1,5,5.1,5.9}]
{-6,-6,5,5,5}
Round[{-.5.9,-5.1,5,5.1,5.9}]
{-6,-5,5,5,6}

Ряд функций обеспечивает нахождение делителей целых чисел и наименьшее общее кратное:

• Divisors[n] — возвращает список целочисленных делителей числа n;

• DivisorSigma[k, n] — возвращает сумму k-x степеней положительных делителей числа n;

• ExtendedGCD[n, m] — возвращает расширенный наибольший общий делитель целых чисел n и m;

• GCD[n1, n2, ...] — возвращает наибольший общий делитель целых чисел ni;

• LCM[n1, n2, ...] — возвращает наименьшее общее кратное целых чисел ni.

Примеры на применение этих функций:

Divlsors[123]
{1,3,41,123}
DivisorSigma[17,3]
129140164
ExtendedGCD[144,12]
{12,{0,1}}
GCD[144,12,6]
6
LCM[124,12,6]
372

К целочисленным функциям можно отнести функции вычисления факториалов: Factorial[n] или n! — возвращает значение факториала числа n; Factorial2[n] или n!! — возвращает значение двойного факториала числа n. Примеры на вычисление факториалов:

Factorial[10]
3628800
20!
2432902008176640000
10!!
3840
20!//N
2.4329X1018
1000!/950!
2877313431200130007024688073066644953223168078601412\
58460384342116480177434914877476604012266378453263443734\
579833577037680948110803599360000000000000

Обратите внимание на то, что знак \ в конце строки означает перевод последующих символов на новую строку.

Следующие функции служат для получения простых чисел и некоторых их характеристик:

• Prime[n] — возвращает n-е простое число (Prime[5] возвращает пятое простое число — 11);

• PrimePi[x] — возвращает число простых чисел, не превышающих х (PrimePi[10] возвращает 4);

• PartitionsP[n] — возвращает число р(n) неупорядоченных разбиений целого числа n (PartitionsP[10] возвращает 42);

• PartitionsQ[n] — возвращает число q(n) разбиений с неравными частями для целого числа n (PartitionsQ[15] возвращает 27).

Эти функции полезны при решении задач теории чисел.

 

Функции генерации случайных чисел

Для реализации статистических методов моделирования используются случайные числа. Система имеет генератор псевдослучайных чисел, доступ к которому обеспечивают функции Random[ ] — возвращает равномерно распределенное псевдослучайное число типа Real в интервале от 0 до 1 и Random[type, range] — возвращает псевдослучайное число указанного типа type, лежащее в указанном интервале range. К возможным типам относятся: Integer, Real и Complex. По умолчанию принят интервал от 0 до 1. Можно задать интервал явно {min, max}; спецификация интервала max эквивалентна {0, max}. Функция SeedRandom[n] устанавливает в начальное состояние генератор случайных чисел, используя целое n как начальное, а функция SeedRandom[ ] устанавливает в качестве начального числа время дня.

 

Функции выявления погрешностей и анализа структуры чисел

Следующие функции используются в основном для выявления погрешностей вычислений и уточнения структуры чисел:

• Accuracy[x] — возвращает количество десятичных цифр справа от десятичной точки числа х;

• EvenQ[expr] — возвращает значение True, если значение выражения ехрr четное, и False — в противном случае;

• IntegerDigits[n] — возвращает список десятичных цифр целого числа n;

• IntegerDigits[n, b] — возвращает список цифр целого n в записи по основанию b;

IntegerDigits[n, b, k] — возвращает список длиной k, содержащий самые младшие (наименьшие) значащие цифры в n;

• Precision[x] — возвращает количество точных знаков в числе х.

Поясним применение этих функций следующими примерами:

Aссurасу[123.456]
14
EvenQ[2*3+2]
True
EvenQ[2*3+3]
False
IntegerDigits[12345]
{1,2,3,4,5}
IntegerDigits[12345,16]
{3,0,3,15}
IntegerDigits[12352,16]
{3,0,4,0}
IntegerDigits[12352,2]
{1,1,0,0,0,0,0,0,1,0,0,0,0,0,0}
Precision[123.452]
16

Функциями Accuracy и Precision возвращаются значения, установленные в последний раз или по умолчанию при первой загрузке системы.

 

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

Для осуществления логических операций используются следующие логические операторы: == — равенство (например, а == b); != — неравенство; > — больше (например, b > а); >= — больше или равно; < — меньше; <= — меньше или равно. Возможны следующие формы их применения: а == b == с; а != b != с и х < у < z и т. д. Результатом исполнения этих выражений является выдача логических значений True или False. Основные логические функции над логическими данными р, q и пр. задаются следующим образом: Not[p] или !р — логическое отрицание; And [р,q,...] или р && q && ... — логическое умножение (логическое И); Or[p,q,...] или р || q || ... — логическое сложение (логическое ИЛИ). Приведем примеры применения логических операторов и функций:

And[True,True,True]
True
True && True && False
False
Not[True]
False
Or[True,True,False]
False
2==2 && 3==3
True
True && True
True
And[1,1,0]
1 || 1 || 0
And[1,1,0]
1 && 1 && 0

К основным логическим средствам относятся и следующие функции: Equal [lhs,rhs]; Greater[x,y]; GreaterEqual[x,у]; Negative[x]; NonNegative[x]; Positive[x]; Xor[e1, e2, ...]. Примеры:

Positive[2-3]
False
Equal[1+2,4-1]
True
Equal[1+2,2]
False
Greater[5,4]
True
Positive[2]
True
NonNeganive[-2]
False
Xor[True,False]
True

Множество других логических функций можно найти в справочной базе данных.

 

Элементарные и специальные функции

Mathematica поддерживает полный набор элементарных функций: Abs[z] — возвращает абсолютное значение для действительного числа и модуль для комплексного z; ArcCos[z] — возвращает арккосинус комплексного числа z, ArcCosh[z] — возвращает значение гиперболического арккосинуса комплексного аргумента z и т. д. В связи с общеизвестностью элементарных функций ограничимся приведением лишь нескольких примеров их использования:

Sqrt[2]
1.41421
2*Sin[1]
2 Sin[1]
N[2*Sin[1]]
1.68294
Log[Exp[1]]
1

Mathematica поддерживает также следующие функции для работы с комплексными числами: Abs[z] — возвращает модуль комплексного числа; Arg[z] — возвращает аргумент комплексного числа z; Conjugate[z] — возвращает комплексно сопряженное с z число; DirectedInfinity[ ] — представляет бесконечную числовую величину с неопределенным направлением на комплексной плоскости; DirectedInfinity[z] — представляет бесконечную числовую величину, являющуюся положительной вещественной кратной комплексному числу z; Im[z] — возвращает мнимую часть комплексного числа z; Re[z] — возвращает вещественную часть числа z. Ниже приведены примеры операций с комплексными числами:

z1:=2+I*3
z2:=4+I*5
N[z1+z2]
6. + 8.1 I
Re[2+I*3]
2
N[Im[z2]]
5.
N[z1/z2]
0.560976 + 0.0487805 I
N[Abs[z1*z2]]
23.0868
Conjugate[z1]
2 - 3 I

Есть также константа ComplexInfinity, означающая комплексную бесконечность. Помимо элементарных функций Mathematica 4 поддерживает самый обширный набор специальных математических функций. С ними можно познакомиться с помощью справочной системы.

 

Расширенные возможности для работы с объектами

 

Оперативная справка

Оперативную справку в ходе работы с системой о назначении какой-либо функции можно получить, используя следующие инструкции: ?Name или Names ["Name"] — справка по заданному слову Name; ??Name — расширенная справка по заданному слову Name; ?Abc* — перечень всех слов, начинающихся с Abc; Options[name] — получение информации о параметрах объекта Name. Примеры на эти операции:

?Sin
Sin[z] gives the sine of z.
??Sin
Sin[z] gives the sine of z.
Attributes[sin] = {Listable, NumericFunction, Protected}

Нетрудно заметить, что есть два уровня оперативной справки. Так, команда ?Sin дает лишь сообщение о назначении функции, a ??Sin предоставляет дополнительную информацию о признаках функции. Все параметры функции Sin позволяет получить команда Names["Sin*"].

 

Средства диагностики и сообщения об ошибках

При ошибке в вычислениях Mathematica выдает сообщение об ошибке в следующем виде: Тип :: Метка%Диагностика:Сообщение. Эти сообщения появляются в отдельных неактивных ячейках. Тип указывает на тип ошибки, например, General — ошибка общего вида, Syntax — синтаксическая ошибка, Arg — ошибка задания аргумента и т. д. Метка указывает место ошибки в списке ошибок данного типа, а Диагностика указывает (увы, не всегда) на ошибочное выражение. Сообщение обычно раскрывает суть ошибки. Для отключения сообщений об ошибках служит инструкция Off [Function::tag]. Для включения сообщения об ошибках используется инструкция On[Function::tag].

Объекты Mathematica имеют средства защиты от модификации и отмены такой защиты. Для этого используются директивы Protect и Unprotect. Защита идентификаторов объектов от модификации является мощным средством контроля правильности вычислений, но в практике обычных вычислений почти не применяется.

 

Операции математического анализа

 

Суммы и произведения

Для вычисления сумм предусмотрена функция Sum, используемая в ряде форм:

• Sum[f, {i, imax}] — вычисляет сумму значений f при изменении индекса i от 1 до imax с шагом +1;

• Sum[f, {i, imin, imax}] — вычисляет сумму значений f при изменении индекса i от минимального значения imin до максимального imax с шагом +1;

• Sum[f, {i, imin, imax, di}] — вычисляет сумму значений f при изменении управляющей переменной вещественного типа от минимального значения imin до максимального imax с шагом di;

• Sum[f, {i, imin, imax}, {j, jmin, jmax}, ...] — вычисляет многократную сумму значений f при изменении индексов i от imin до imax с шагом +1, j от j min до j max с шагом +1 и т. д.

Примеры использования функций суммирования:

Sum[i^2,{i,1,2,0.25}]
11.875

770
Sum[xiyj,{i,1,4},{j,1,4}]
ху+х2у+х3у+х4у+х2у23у24у23у34у34у4

Для вычисления сумм в численном виде используются те же функции с добавлением в начало имени буквы N, например NSum[f, {i, imin, imax}]:

Nsum[1/i^3,{i,1,¥}]
1.20206

Операции вычисления произведений представлены функциями Product в той же нотации, что и Sum:

Product[i,{i,10}]
3628800
NProduct[k^2,{k,1,5}]
14400,
NProduct[i^2,{i,1,2,0.2}]
93.6405
Product[Log[i],{i,2,5,0.5}]
4.23201 Log[2]

 

Вычисление производных и интегралов

Для вычисления производных используются следующие функции: D[f,x] — возвращает частную производную функции f по переменной x; D[f, {x, n} ] — возвращает частную производную n-го порядка по x; D[f, x1, х2, ...] — возвращает смешанную производную; Dt[f, х] — возвращает обобщенную производную функции f по переменной x; Dt[f] — возвращает полный дифференциал f.

Для функции D существует параметр NonConstants, который возвращает список объектов, находящихся в неявной зависимости от переменных дифференцирования. По умолчанию список пуст. Аналогично, для функции Dt имеется параметр Constant (по умолчанию возвращает пустой список). На практике применение данных параметров встречается редко. Существует еще одна функция Derivative[n1, n2, ...][f] — основная (общая) форма представления функции, полученной в результате дифференцирования f n1 раз по первому аргументу, n2 раз по второму аргументу и т. д. К примеру, Derivative[2][x*y] возвращает (х у)'', a Derivative[2, 3][х*у] — соответственно, (х у)(2,3). Примеры:

D[x*Sin[x],x]
xCos[x]+Sin[x]
D[BesselJ[2,x],x]

D[ChebyshevT[4,x],x]
16x+32x3
f[x]:=x/(1+x-2)
D[f[x],x,3]

Использование функции Dt демонстрируют примеры, приведенные ниже:

Dt[x^n,x]
nx-1+n+xnDt[n,x]Log[x]
Dt[ChebyshevT[4,x],x]
-16x+32x2

Для интегрирования в системе Mathematica используются следующие функции:

• Integrate[f, х] — возвращает неопределенный интеграл от функции f по переменной х;

• Integrate[f, {x, xmin, xmax}] — возвращает значение определенного интеграла с пределами от xmin до xmax по переменной х;

• Integrate[f, {x, xmin, xmax}, {у, ymin, ymax},...] — возвращает значение кратного интеграла с пределами от xmin до xmax по переменной х, от ymin до ymax по переменной у и т. д. (кратность реально не ограничена).

Обычно функция Integrate применяется прямо, но она имеет три характерных параметра, список которых позволяет получить команда Options[Integrate].

Для обозначения бесконечных пределов используется константа Infinity. Пределы могут задаваться как константами, так и функциями. Ниже даны примеры символьного интегрирования:



Integrate[{Sin[x],Tan[x],Cosh[x],ArcSin[x]},x]




EulterGamma-CosIntegral[x2y]+Log[x2y]



В последнем примере интеграл является частью условного выражения.

Для вычисления численных значений определенных интегралов используется функция NIntegrate[f, {x, xmin, xmax}]. Она возвращает численное приближение интеграла от функции f по переменной х на интервале от xmin до xmax и имеет ряд параметров. С ними можно ознакомиться по справочной системе. Полный перечень параметров выводится командой Options[NIntegrate]. Приведем примеры на использование функции Nintegrate:

NIntegrate[Sqrt[2*x+1],{x,0,1}]
1.39872
NIntegrate[1/(x*y),{x,4,4.4},{y,2,2.6}]
0.025006
NIntegrate[x*y,{x,
0,1},{у,х,х^2},{z,x*y,x^2*y^3}]
0.010582

Функция NIntegrate с успехом может применяться и для вычисления кратных интегралов и интегралов с переменными пределами.

 

Вычисление пределов функций

Для вычисления пределов выражения ехрr используется функция Limit[expr, opts], где параметр opts задает точку, для которой ищется предел, и направление подхода к пределу:






 

Решение уравнений в символьном виде

Для решения уравнений (как одиночных, так и систем) в численном и символьном видах Mathematica поддерживает функцию Solve[eqns, vars], обеспечивающую решение системы equns относительно переменных vars, и Solve[eqns, vars, elims], обеспечивающую решение с исключением переменных elims. Входные параметры этой функции могут быть представлены списками или записанными через объединительный знак && выражениями. В eqns в качестве знака равенства используется знак ==. Примеры на применение функции Solve представлены ниже:

Solve[2*x^2 - 5*х - 10 == 0, х]

Solve[{x^2+y^2+z==5,x*y+z==2,x+y+z==3},{x,y,z}]
{{z®0,x®1,y®2},{z®0,x®42,y®1},{z®3,x®1,y®1},{z®3,x®1,y®-1}}

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

N[Solve[x3-y^2==6&&x^2-y==3,x,y]]
{{у® 0.345604,х® 1.8291},{у® 2.86285,x® 2.42133},
® -1.10423-2.80661,х® -1.62522+0.863454I},
® -1.10423+2.80661,х® 1.62522-0.863454I}}

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

е=х==2+3 ах, у==5+2х
{х==2+3ах,у==5+2х}
r=Solve[e,x,y]

e/.r

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

Simplify[%]
{{True,True}}

Этот пример показывает, что решение все же верно, хотя подстановка не дала сразу явный результат в виде {{True}, {True}}. Теперь рассмотрим простую и явно имеющую решение (например, при х=2 и у=3) систему уравнений х*у=6 и х^2+у=7:

eqns={x*y==6, х^2+у==7}
result=Solve[eqns,{х,у}]
{{у® -2,х® -3},{у® 3,х® 2},{у® 6,х® 1}}
eqns/.result
{{True,True}, {True,True}, {True,True}}

Оказывается, что Mathematica в этом случае дает сразу три пары решений, и все они верны, поскольку после подстановки получены все утверждения True. В следующем примере показано решение системы нелинейных уравнений с помощью функции Solve:

Solve[{x^2+y==a,y^2==a+b},{x,y}]

С функцией Solve можно использовать ряд параметров, выводимых командой Options[Solve].

Приведем пример на применение функции Solve с параметром InverseFunctions:

Solve[2*Sin[x/2]*Sec[2*x]^-1==0,x,InverseFunctions->True]

Степень влияния на решение параметра Method наглядно иллюстрирует следующий пример:

Solve[x^3-y^2==7&&x^2-y==3,х, у, Method->1 ]
{{-6х234® -16,у® -3+х2}}

Если теперь задать Method->3, то будет получен куда более сложный, но численный результат.

 

Численное решение уравнений

Для численного решения систем нелинейных уравнений используется функция NSolve[eqns, vars], которая пытается решать численно одно уравнение или систему уравнений относительно переменных vars, и NSolve[eqns, vars, elims], которая пытается решать численно уравнения относительно переменных vars, исключая переменные elims. Единственный параметр этих функций — WorkingPrecision — определяет число верных цифр результата (по умолчанию 16). Приведем примеры использования функции NSolve для численного решения уравнений:

NSolve[y*x^2==9,х*у^2==3,х,у]
{{х® -1.5-2.598081,у® -0.5-0.866025},
® -1.5+2.598081,у® -0.5+0.8660251},{х® 3.,у->1.}}
е=2*х
^2 + 5*х - 15 == х^3
-15+5х+2х2==х3
r=Nsolve[e,x]
{{х® -2.4734},{х® 2.2367-1.03038I},{x® 2.2367+1.03038I}}
е/.r
{True, True, True}

Для вычисления корней уравнений, например многочленов, используется функция Roots[lhs==rhs, var]. Она дает дизъюнкцию уравнений, которая представляет корни уравнения. Следующие примеры иллюстрируют применение функции Roots:

Roots[x^2+2*x+15==0,x]

Roots[x^5+8*x^4+31*x^3+80*x^2+94*x+20==0,x]

Формат выдачи результатов у функции Roots отличается от такового для функции Solve. Поэтому проверку решения подстановкой надо выполнять следующим образом:

е=х^2 + 3х == 2
Зх+х2==2
N[Roots[e,x]]
x == -3.56155 ||
х == 0.56133
r={ToRules[%]}
{{х -> -3.56155}, {х -> 0.56133}}
е/.
r
{True, True}

Для преобразования результата вычислений в список решений (подобный решениям с помощью функции Solve) использована функция ToRules. При затруднениях в решении уравнений с помощью функции Roots допускаются следующие параметры, выводимые командой Options[Roots]. Применение параметров нередко позволяет получать решения, которые не удаются с первого раза. На рис. 9.15 показан пример нахождения всех корней уравнения xsin•(x)+x/2-1=0. Полезно разобрать этот пример.

 

Рис. 9.15. График функции х•sin(x)+x/2-l и пример вычисления всех ее корней в интервале изменения х от 20


Специальный формат результатов не позволяет использовать неизвестные в явном виде. Однако от этого затруднения легко избавиться, если перед конструкцией блока решения задать выражение следующего вида: {х,у,
z,...}/.. Ниже этот прием показан в действии:

FindRoot[{x^2==9ly^2==16,x+y+z==10},{x,1.},{у.1.},{z,1.}]
{х->3.,у->4.,z->3.}
{x,y,z}
{x,y,z}

Теперь зададим решение в виде

{x,y,z}/.FindRoot[x^2==9,y^2==16,x+y+z==10,x,1.,y,1.,z,1.]
{3.,4.,3.}

Следующее решение получено в виде списка с числами — явными значениями неизвестных:

{а,b,с}=%
{3.,4.,3.}
а,b
{3.,4.,3.}
а
3.
b
4.
с
3.

Можно проверить решение данной системы:

{a^2,b^2,a+b+c}
{9.,16.,10.}

Полученный вектор правых частей системы совпадает с заданным, что свидетельствует о правильности решения. Разумеется, вместо нового списка {а, b, с} для вектора решения можно было использовать и вектор {х, у, z}.

 

Решение дифференциальных уравнений

 

Решение в символьном виде

Для решения ДУ в символьном виде используются следующие средства:

• функция DSolve[eqn, у[х], х] — решает ДУ относительно функций у[х] с независимой переменной х;

• функция DSolve[{eqn1, eqn2, ...}, {у1[х1, ...], ...}, {x1, ...}] — решает систему ДУ;

• параметр DSolveConstants — определяет постоянные интегрирования;

• параметр StartingStepSize — определяет величину начального шага.

В решении ДУ встречаются постоянные интегрирования. В общем случае они обозначаются как С[i]. Приведем примеры решения ДУ:

DSolve[Derivative[1][y][x] == 2*а*х^3, у[х], х]

Dsolve[y'[x]==Sin[Ex],y[x],x]
{{y[x]® C[1]+SinIntegral[Ex]}}
Dsolve[x2w"[z]+zw'[z]-(z2+1)w[z]==0,w[z],z]

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

 

Решение в численном виде

Для численного решения систем ДУ используются следующие функции: NDSolve [eqns, у, {х, xmin, xmax}] — ищет численное решение ДУ eqns относительно функции y независимой переменной х в интервале от xmin до xmax; NDSolve[eqns, {y1, y2, ...}, {х, xmin, xmax}] — ищет численные решения относительно функций yi. Кроме того, имеется параметр MaxSteps к функции NDSolve, который определяет максимальное количество шагов. Пример решения системы ДУ с построением графика решения дан на рис. 9.16.

 

Рис. 9.16. Решение системы ДУ с выводом решения в виде графиков временных зависимостей


Нередко решение предпочитают представлять на фазовой плоскости. Рис. 9.17 иллюстрирует такую возможность. Более того, учитывая, что решается система из трех ДУ, фазовая траектория решения находится в трехмерном пространстве. Простота задания решения и вывода его результатов в графической форме открывает широкие возможности в применении системы для математического моделирования сложных явлений.

 

Рис. 9.17. Решение системы ДУ с выводом решения в форме кривых на фазовой плоскости

 

Разложение функций в степенной ряд

Для разложения функций в ряд Тейлора используются следующие функции:

• Series[f, {x, x0, n}] — выполняет разложение в степенной ряд функции f в окрестности точки х=х0 по степеням (х-х0)^n;

• Series[f, {x, х0, nх}, {у, у0, nу}] — последовательно ищет разложения в ряд сначала по переменной у, затем по х;

• SeriesCoefficient[s, n] — возвращает коэффициент при переменной n-й степени ряда s;

• SeriesData[x, х0, {а0, а1, ...}, nmin, nmax, den] — представляет степенной ряд по переменной х в окрестности точки х0. Величины ai являются коэффи циентами степенного ряда.

Показатели степеней (х-х0) представлены величинами nmin/den, (nmin+D/den,..., nmax/den. Обычно разложение сложнее дает некоторую остаточную погрешность — член 0[х]i:

Series[Tanh[x],{x,0,7}]

Series[Sin[x*y]1{x,0,5},{y,0,5}]

Для устранения остаточного члена и получения приемлемых для расчетов выражений можно использовать функции Collect и Normal. Ниже показаны примеры на использование этих функций:

Series[Sin[x],{x,0,7}]

Collect[%,x]

Normal[Series[Sin[x*y],{x,0,3},{у,0,3}]]

f[x_,y_]=xy-x^3y^3/6

f[0.1,0.2]
0.0199987

В данном случае результат представлен в формате стандартного вывода. Его можно использовать для создания функций пользователя, например, путем переноса через буфер обмена в правую часть такой функции. Это и показано в конце приведенных выше примеров. Разумеется, можно задать функцию пользователя и напрямую:

F[x_,y_]=Normal[Series[Sin[x*y],{х,0,3},{у,0,3}]]

F[0.1,0.2]
0.0199987

 

Дискретное преобразование Фурье

Быстрое прямое и обратное преобразования Фурье (БПФ) Mathematica 4 реализует функциями Fourier[list] и InverseFourier[list]. Преобразование выполняется для списка list комплексных чисел. Результаты прямого и обратного преобразований Фурье должны приводить к результату, совпадающему с исходными данными (в пределах малой погрешности):

DF:=Fourier[{1,1,0,0}]
DF
{1.+0.1,0.5+0.5I,0.+0/I,0.5-0.5I}
IF:=InverseFourier[DF]
IF
(1.+0.I,1+2.77556´ 10-17I,0.+0.I,0.-2.77556´ 10-17)

Прямое преобразование Фурье означает перевод временного представления сигнала в частотное представление, то есть позволяет получить частотный спектр сигнала, представленного отсчетами его временной зависимости. Это поясняет документ, показанный на рис. 9.18 и демонстрирующий выделение исходных компонентов из спектра зашумленного сигнала.

 

Рис. 9.18. Получение спектра сигнала с помощью прямого преобразования Фурье


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

 

Рис. 9.19. Часть документа, показывающая создание сигнала и синтез его фильтра


Как и в ранее рассмотренном примере, сигнал формируется как сумма чистого сигнала со случайным компонентом, моделирующим шум. Выбранная форма сигнала напоминает затухающую синусоиду. Уровень шумов выбран достаточно большим, так что форма чистого сигнала с трудом угадывается на фоне шумов (верхний график). Далее показан синтез частотного фильтра и его амплитудно-частотная характеристика (АЧХ). Ее пик должен примерно соответствовать средней частоте спектра сигнала. График АЧХ показан в нижней части рис. 9.19.

На следующем рисунке (рис. 9.20) показан процесс фильтрации. Он сводится к уточнению модели фильтра (ротации АЧХ в область отрицательных частот) проведению вначале прямого преобразования Фурье, выделению фильтром соответствующих составляющих сигнала и последующему обратному преобразованию Фурье. Оба преобразования и фильтрация осуществляются в одном выражении. При этом частотные отсчеты сигнала и фильтра перемножаются. Обратное преобразование Фурье переводит результат фильтрации во временную область. Полученный в результате фильтрации сигнал практически очищен от шума.

 

Рис. 9.20. Часть документа, иллюстрирующего фильтрацию сигнала и построение его графика


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

 

Интерполяция данных и аппроксимация функций

 

Полиномиальная интерполяция и аппроксимация

Для решения задач интерполяции и аппроксимации данных, заданных рядом узловых точек, в Mathematica используются следующие функции:

• InterpolatingFunction[range, table] — возвращает интерполирующую функцию, позволяющую вычислять промежуточные значения в заданном диапазоне range для таблицы table;

• InterpolatingPolynomial[data, var] — возвращает полином (степенной многочлен) по переменной var, значения которого в узловых точках точно совпадают с данными из списка data;

• Interpolation[data] — конструирует объект InterpolatingFunctlon.

InterpolationOrder — параметр к функции Interpolation, который определяет степень подходящего полинома. Применение основной функции Interpolation поясняет следующий пример:

data=Table[{x,x^2+1},{x,1,5}]
{{1,2},{2,5},{3,10},{4,17},{5,26}}
funi=Interpolation[data]
InterpolatingFunction[{{1,5}},<>]
{funi[1,5],funi[3],funi[4,5]}

{3.25,10,21.25}

Пример на рис. 9.21 иллюстрирует технику проведения полиномиальной аппроксимации.

 

Рис. 9.21. Полиномиальная аппроксимация таблично заданных данных


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

 

Рациональная Паде-аппроксимация

Более высокую точность, чем у полиномиальной аппроксимации, обеспечивает рациональная Паде-аппроксимация (рис. 9.22).

 

Рис. 9.22. Паде-аппроксимация


На рис. 9.22 показан также пример вызова конкретной функции из одного из пакетов расширений системы.

 

Регрессия и визуализация ее результатов

Для решения задач регрессии в системе Mathematica 4 используется функция Fit[data, funs, vars], которая для списка данных data ищет приближение методом наименьших квадратов в виде линейной комбинации функций funs переменных vars. Примеры ниже иллюстрируют приближение исходных данных степенным полиномом и линейной комбинацией двух функций:

Fit[{{0,0.9},{2,8.1},{3,17},{4,33}},{1,x,x2},x]
0.997273-1.40864х+2.33409х2
Fit[{{0,0.9},{2,8.1},{3,17},{4,33}},{x,x2,Exp[x]},x]
0.274772ех+1.63939х+0.717496х2

На рис. 9.23 показан несколько иной путь проведения полиномиальной аппроксимации — исходные данные заданы объектом-списком data.

 

Рис. 9.23. Полиномиальная регрессия с графическим выводом


В конце документа на рис. 9.23 дан график аппроксимирующего полинома и точек исходных данных. Заметно, что при регрессии график полинома проходит в середине “облака” исходных точек и не укладывается на них точно.

 

Функции минимизации и максимизации

 

Поиск максимального и минимального чисел в списке

Для поиска максимального и минимального значений ряда чисел, входящих в список, система Mathematica предоставляет следующие функции:

• Мах[х1, х2, ...] — возвращает наибольшее из значений xi;

• Мах[{х1, х2, ...}, {у1, ...}, ...] — возвращает наибольший элемент любого из списков;

• Min[x1, x2, ...] — возвращает наименьшее из значений xi;

• Min[{x1, x2, ...}, {y1, ...}, ...] — возвращает наименьший элемент любого из данных списков.

Следующие примеры иллюстрируют действие этих простых функций:

Мах[1,5,2,6.5,3,4]
6.5
Мах[{1,3,2},{4,5,6},{9,8,7}]
9
Min[1,5,2,6.5,-3,4]
-3
Min[{1,3,2},{4 5 6},{9,8,7}]
1

 

Поиск локального минимума аналитической функции

Если нужен поиск локального минимума некоторой аналитической функции, используется функция FindMinimum[f, {х, х0}]. Она выполняет поиск (начиная со значения х=х0) и возвращает значение локального минимума f. Чтобы задать градиент функции, для которой выполняется поиск минимума, используется параметр Gradient. Приведем примеры применения функции FindMinimum:

FindMinimum[-5x Exp[-x/2](2+Sin[3x],{x,1})
{-7.17833,{х->0.783139}
FindMinimum[100(y-x2)2+(1-x2)2,{x,0},{y,0},AcuracyGoal->Automatic]
{9.90511´ 10-13,{х->1.,у->0.999999}}

Если необходимо разыскивать локальные максимумы, достаточно перед функцией поставить знак минус или умножить ее на -1.

 

Поиск глобального максимума и минимума аналитической функции

Следующие две функции служат для поиска глобального максимума и минимума аналитически заданной функции: ConstrainedMax[f, {inequalities}, {х, у, ...}] — ищет глобальный максимум функции f в области, определяемой неравенствами inequalities; ConstrainedMin[f, {inequalities}, {х, у,...}] — ищет глобальный минимум функции f в области, определяемой неравенствами inequalities. Все переменные х, у, ... полагаются неотрицательными. Эти функции решают типовые задачи линейного программирования. Может использоваться функция Linear Programming[c, m, b]. Она ищет вектор х, минимизирующий величину с. х в соответствии с условиями m.х >= b и x >= 0.

Рассмотрим типичный пример линейного программирования. Пусть цех малого предприятия должен изготовить 100 изделий трех типов, причем не менее 20 штук каждого типа. На изготовление этих изделий уходит, соответственно, 4, 3,4 и 2 кг металла при его общем весе 340 кг и 4,75, 11 и 2 кг пластмассы при ее общем весе 700 кг. Спрашивается, сколько изделий х1, х2 и х3 каждого типа надо выпустить для обеспечения максимальной стоимости продукции, если цена каждого из изделий равна, соответственно, 4,3 и 2 рубля. Ниже представлено решение этой задачи:

ConstrainedMax[
    
4*х1+3*х2+2*х3,
    {х1>=20,х2>=20,х3>=20,
    4*х1+3.4*х2+2*хЗ<=340,
    4.75*х1+11*х2+2*хЗ<=700,
    х1+х2+х3==100},
    {х1,х2,х3}]
{332.,х1® 56.,х2® 20.,х2® 24.}

После имени функции указывается максимизируемая целевая функция, затем — все ограничения и, наконец, список искомых переменных. Результатом вычислений является стоимость продукции и количество изделий, представленное списком. Задачи минимизации традиционно относятся к сложным задачам программирования — особенно при поиске глобального минимума.

 

Массивы

 

Задание массивов

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

• Array[f, n] — генерирует список длиной n с элементами f[i];

• Array[f, {n1, n2, ...}] — генерирует массив с размером n1´ n2´ ... в виде вложенных списков с элементами f[i1, i2, ...];

• Array[f, dims, origin] — генерирует список с размерностью dims, используя спецификацию индекса origin;

• Array[f, dims, origin, h] — использует заголовок h, а не List, для каждого уровня массива.

Примеры задания массивов и их вывода:

Y:=Array[Exp,4]
Y
{Е, Е2 , Е3 , Е4}
N[Y]
{2.71828, 7,38906, 20.0855, 54.5982}
Array[f,{3,3}]
{{f[i,1],f[i,2],f[1,3]},
{f[2,1],f[2,2],f[2,3]},
{f[3,1],f[3,2],f[3,3]}}
Array[Sin,3,0]
{0,Sin[1],Sin[2]}
Array[Sin,4,1,Plus]
Sin[1]+Sin[2]+Sin[3]+Sin[4]
Array[f,5,2,2]
2[f[2],f[3],f[4],f[5],f[6]]

 

Функции для операций линейной алгебры

Следующая группа функций системы Mathematica позволяет осуществить основные операции над векторами и матрицами, используемыми в линейной алгебре:

• Cross[v1, v2, v3,...] — кросс-произведение векторов (может задаваться в виде v1*v2*v3*...);

• Det[m] — возвращает детерминант (определитель) квадратной матрицы m;

• DiagonalMatrix[list] — возвращает диагональную матрицу с главной диагональю, сформированной из элементов списка list и нулевыми остальными элементами матрицы;

• Dot [a, b, с] — возвращает произведения векторов, матриц и тензоров (операцию произведения можно задавать также и в виде а. b. с);

• Eigensystem[m] — возвращает список {values, vectors} собственных значений и собственных векторов данной квадратной матрицы m;

• Eigenvalues[m] — возвращает список собственных значений квадратной матрицы m

• Eigenvectors[m] — возвращает список собственных векторов квадратной матрицы m;

• IdentityMatrix[n] — возвращает единичную матрицу с размером n´ n (у нее диагональные элементы имеют значения 1, остальные 0);

• Inverse[m] — возвращает обратную матрицу для квадратной матрицы m, то есть матрицу m-1, которая, будучи умноженной на исходную матрицу, дает единичную матрицу;

• LinearSolve[m, b] — возвращает вектор х — решение матричного уравнения m. х==b, где — матрица коэффициентов левой части системы линейных уравнений, х — вектор неизвестных и — вектор свободных членов в правой части системы;

• MatrixExp[m] — возвращает экспоненциал матрицы m;

• MatrixPower[m, n] — возвращает n-ю степень матрицы m;

• MatrixQ[expr] — возвращает True, если ехрr является списком списков, который может представлять матрицу, иначе возвращает False;

• MatrixQ[expr, test] — возвращает True, только если test дает True в применении к каждому элементу матрицы в ехрr;

• Minors[m, k] — возвращает матрицу, составленную из определителей всех k´ k субматриц m;

• NullSpace[m] — возвращает список векторов, которые формируют базис для нулевого пространства матрицы m;

• Pivoting — параметр, относящийся к функциям декомпозиции матрицы, указывает, что должен выполняться поворот столбца. Результат имеет форму {Q, R, Р}, где Р — матрица перестановок, такая, что имеет место M. P=Conjugate[Transpose [Q]]. R, где М — начальная (исходная) матрица;

• PseudoInverse[m] — ищет псевдообратную квадратной матрице m;

• Tr[list] — возвращает след матрицы или тензора (только в Mathematica 4);

• Traspose[m] — возвращает транспонированную матрицу, у которой столбцы и строки меняются местами, в сравнении с матрицей m;

• QRDecomposition[m] — возвращает QR-разложение (декомпозицию) для числовой матрицы m, результат представляет собой список {q, r}, где — ортогональная матрица, r — верхняя треугольная матрица;

• RowReduce[m] — возвращает приведенную к строке форму матрицы m,

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

Следующие примеры иллюстрируют применение некоторых из этих функций:

A:=MentityMatrix[3]
A
{{1,0,0},{0,1,0},{0,0,1}}
MatrixExp[A]
{{Е,0,0},{0,Е,0},{0,0,Е}}
MatrixQ[A]
True
MatrixPower[MatrixExp[A],-1.5]
{{0.22313,0,0},{0,0.22313,0},{0,0,0.22313}}
А+{{1,2,3),{4,5,6},(7,8,9}}
{{1,2,3},{4,6,6},{7,8,10}}
m:={{1,2},{3,7}}
MatrixForm[m]
1  2
3  7
Det[m]
1
Inverse[m]
{{7,-2},{-3,1}}
MatrixQ[m]
True
RowReduce[m]
{{1,0},(0,1}}
m = {{1,2},{3,7}}
{{1,2},{3,7}}
Transpose[m]
{{1,3},{2,7}}
Inverse[{1,2},{3,7}]
{{7,-2},{-3,1}}

 

Решение систем линейных уравнений

Приведем примеры на решение систем линейных уравнений матричными методами. В первом из них решение выполняется в символьном виде на основании формулы Х=А-1В, где А — матрица коэффициентов системы линейных уравнений, В — вектор свободных членов. Для перемножения используется функция Dot, а для инвертирования матрицы — функция Inverse:

A:={a,b,c,d}
B:={e,f}
X:=Dot[Inverse[A],B]
X

Во втором примере для вычисления неизвестных системы линейных уравнений используется функция LinearSolve:

LinearSolve[1,2,3,4,7,9]
{-5,6}

Нередко, например в электротехнических расчетах, встречается необходимость решения систем линейных уравнений с комплексными элементами. Все описанные выше функции обеспечивают работу с комплексными числами. Следующий пример иллюстрирует решение системы линейных уравнений с комплексными данными:

А={{1+2I,2+3I},{3+4I,4+5I}}
{{1+2I,2+3I}, {3+4I,4+5I}}
В={2I,3}
{2I,3}
X=LinearSolve[A,B]

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

 

Символьные вычисления

 

Выражения

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

Выражение

Полная форма

Описание

x+y+z

х у z

х^n

{а,b,с}

а->b

а=b

Plus[x,y, z]

Times[x, у, z]

Power[x, n]

List[a, b, c]

Rule[a,b]

Set[a,b]

Сложение

Умножение

Возведение в степень

Создание списка

Подстановка

Установка

Для вывода выражения ехрr в полной форме используется функция FullForm[expr]:

1+x^2+(y+z)^2+2
3+x2+(y+z)2
FullForm[%]
Plus[3,Power[x,2],Power[Plus[y,z],2]]

Имеются четыре основные формы записи выражений:

• f[х,у] — стандартная форма для f[х,у],

• f @ х — префиксная форма для f[х];

• х // — постфиксная форма для f[x];

• х ~ f ~ у — инфиксная форма для f[x,у].

Примеры применения этих форм:

F[x_]=2*x^2
2 х2
F[a]
2 а2
a//F
2 а2
f[x_,y_]=x^2+y^2
x2+y2
f[a,b]
a2+b2
а~f~b
a2+b2

Для выделения любой заданной части выражений используются функция Part или двойные квадратные скобки. Следующие функции возвращают особые части выражения:

• Denominator[expr] — возвращает знаменатель выражения expr;

• First[expr] — возвращает первый элемент в expr;

• Last [expr] — возвращает последний элемент в expr;

• Rest[expr] — возвращает expr с удаленным первым элементом.

Примеры применения этих функций:

Denominator[(x+1)/(x^2+2*x+3)]
3+2х+х2
expr=a*b+c-d
ab+c-d
First[expr]
ab
Last[expr]
-d
Rest[expr]
c-d

Иногда возникает необходимость в удалении части выражения. Для этого применяется функция Delete[expr, n]. Она удаляет элемент на позиции n в выражении ехрr. Если n отрицательно, позиция отсчитывается с конца. Есть и ряд других форм этой функции.

 

Функции

Следующие функции применяются к выражению или к частям выражения:

• Apply [f, expr] — замещает заголовок выражения expr на f;

• Nest[f, expr, n] — возвращает выражение, полученное n-кратным применением f к expr;

• Map[f, expr] — применяет f к каждому элементу на первом уровне в expr;

• Map[f, expr, levelspec] — применяет f к частям expr, указанным с помощью levelspec;

• MapAll[f, expr] — применяет f ко всем частям выражения expr.

Примеры на действие этих функций:

Appiy[f,{a,b,х}]
f[a,b,x]
Nest[f,x,3]
f[f[f[x]]]
s[x_,y_,z_]:=x+y-b
N[Apply[s,{1,2,a}]]
3.+b
Map[f,{a,b,c}]
{f[a],f[b],f[c]}
MapAll[f,a*x+b]
f[f[b]+f[f[a]f[x]]]

Наряду с полной формой функции также могут задаваться укороченной формой:

f @ expr
f[expr]
f @@ expr
Apply[f, expr]
f /@ expr
Map[f, expr]
f //@ expr
MapAll[f, expr]

Смысл укороченных выражений очевиден:

f@{a,b,c}
f[{a,b,c}]
f@@{a,b,c}
f[a, b,c]
f/@{a,b,c}
{f[a],f[b],f[c]}
f//@{a,b,x}
f[{f[a],f[b],f[x]}]

Укороченная форма функций может оказаться полезной для сокращения записи алгоритмов и программ.

 

Упрощение выражений

Основной функцией упрощения выражений expr является функция Simplify[expr]:

Simplify[a*a-2*a*b+b^2]
(a-b)2
Simplify[Sin[x-y]+Sin[x+y]]
2Cos[y]Sin[x]
Simplify[Exp[x]*Exp[y]/Exp[z]]
Ex+y+z
Simplify[Exp[z*Log[b]]]
b2
Simplify[g*Log[10]]
6Log[10]

Функция FullSimplify, область применения которой в Mathematica 4 заметно расширена, обладает большими возможностями, чем функция Simplify. В частности, она обеспечивает лучшее упрощение выражений, содержащих специальные математические функции:

Simplify[Gamma[x]*x*(x-1)*(x-2)*(x+n)]
x(1+x)(2+x)(n+x)Gamma[x]
FullSimplify[Gamma[x]*x*(x-1)*(x-2)*(x+n)]
(n+x)Gamma[3+x]

Как видно из этих примеров, функция FullSimplify обеспечивает упрощение даже в том случае, когда функция Simplify пасует. Неплохо упрощаются тригонометрические функции, особенно при использовании параметра ComplexityFunction, задающего путь упрощения.

 

Раскрытие и расширение выражений

Ниже представлены основные функции, возвращающие результаты раскрытия и расширения выражений:

• ComplexExpand[expr] — раскрывает выражение expr, полагая все переменные вещественными;

• ComplexExpand[expr, {x1, х2, ...}] — раскрывает выражение expr, полагая переменные в списке соответствующими какому-либо действительному значению;

• FunctionExpand[expr] — раскрывает выражение expr, содержащее специальные функции;

• Expand[expr] — раскрывает произведения и положительные целые степени в expr;

• Expand[expr, patt] — не выполняет расширение для тех элементов expr, которые не содержат соответствующие шаблону patt члены;

• ExpandAll[expr] — раскрывает все произведения и целочисленные степени в любой части expr;

• ExpandAll[expr, patt] — исключает из операции расширения те части expr, которые не содержат соответствующие шаблону patt члены;

• ExpandDenominator[expr] — раскрывает произведения и степени, которые присутствуют в выражении expr в роли знаменателей;

• ExpandNumerator[expr] — раскрывает произведения и степени в числителе выражения expr;

• PowerExpand[expr] — раскрывает вложенные степени, степени произведений, логарифмы от степеней и логарифмы от произведений.

Приведем примеры на функции расширения выражений Expand:

Expand[(x-a)*(x-b)*(x-c)]
-abc + abx + acx + box - ax2 - bx2 - cx2 + x3
Expand[2*Cos[x^2,Trig->True]]
2Cos[x]2
Expand[Sin[x]^2+Cos[x]^2]
Cos[y]2+Sin[x]2
ExpandAll[Sin[2*Cos[x]],Trig->True]
Cos[Cos[x]+Isin[x]]Sin[Cos[x]-Isin[x]]+
Cos[Cos[x]-Isin[x]]Sin[Cos[x]+Isin[x.]]
ExpandNumerator[(1+x)^2/x]

ExpandDenominator[(1-x)^2/(1+x)^2]

ComplexExpand[Sin[a+I*b]]
Cosh[b]Sin[a]+Icos[a]*Sinh[b]
PowerExpand[Sqrt[a^2*b*c]]

FunctionExpand[Zeta[3, 2+x]]

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

 

Функция Collect

К функциям, расширяющим выражения, относятся также функция Collect[expr, х], которая выполняет приведение общих членов выражения по степеням переменной х, и функция Collect[expr, {х1, х2, ...}], которая выполняет приведение общих членов выражения по степеням переменных х1, х2,... Эта функция особенно полезна, если результат можно представить в виде степенных многочленов:

Collect[(х-1)*(х-2)*(х^2-9),х]
-18+27х-7х2-3х34
Collect[a*x^2+b*x*y_c*y+d*y^2,x]
ax2+cy+bxy+dy2
Collect[a*x^2+b*x*y+c*y+d*y^2,
у]
ax2+(c+bx)y+dy2

В другом примере показано применение функции Collect к выражению с двумя переменными:

Collect[(x-1)*(y-3)*(x-2)*(y-2)*(x-1),y,x]
-12+30х-24х2+6х3+(10-25х+20х2-3)у+(-2+5х-4х232

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

 

Функции преобразования тригонометрических выражений

Хотя представленные выше функции иногда применимы для тригонометрических выражений, для последних есть ряд специальных функций, дающих более надежные результаты в ходе преобразований. В названии этой группы функций имеется слово Trig. Начнем с функции TrigExpand[expr], которая обеспечивает расширение выражения expr, содержащего тригонометрические и гиперболические функции. Представленные ниже примеры иллюстрируют работу этой функции:

TrigExpand[Sin[a+b]]
Cos[b]Sin[a]+Cos[a]Sin[b]
TrigExpand[Cos[3*x]]
Cos[x]3-3Cos[x]Sin[x]2
TrigExpand[Sinh[x]]
2Cosh[x]Sinh[x]

Приведем еще две функции: TrigToExp[expr] — преобразует тригонометрические выражения к экспоненциальному виду и ExpToTrig[expr] — преобразует экспоненциальные выражения в тригонометрические. Ниже даны примеры на применение этих функций:

f:=Sinh[z]+Cosh[z]
TrigToExp[f]
Ez
ExpToTrig[%]
Cosh[z]+Sinh[z]

Приведем еще две функции: TrigFactor[expr] — раскладывает на простые множители тригонометрическое выражение expr и TrigFactorList[expr] — раскладывает тригонометрическое выражение expr на листы с термами выражения. Следующие примеры иллюстрируют применение этих функций:

expr=TrigExpand[Sin[a+b]^3];
TrigFactor[expr]
Sin[a+b]3
TrigFact
оrList[ехрr]
{{1,1},{Sin[a+b],3}}
Trig Expand[Cosh[Sin[x*y]]]

TrigFactorList[%]
{{1,1},{Cosh[Sin[xy]],1}}

Функция TrigReduce[expr] также упрощает выражения с произведениями тригонометрических функций:

TrigReduce[2*Sin[x]*Cos[y]]
Sin[x-y] + Sin[x+y]
TrigReduce[Cosh[x]*Tanh[x]]
Sinh[x]

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

 

Разложение полиномов

Разложение чисел, математических выражений и особенно полиномов на простые множители так же распространено, как и использование функций Simplify, Collect и Expand. Имеется целый ряд функций, в названии которых есть слово Factor и которые решают указанные задачи:

• Factor[poly] — выполняет разложение полинома poly с целыми числами, параметр Modulus->p позволяет выполнить разложение полинома по модулю простого р;

• FactorInteger[n] — возвращает список простых множителей целого числа n вместе с их показателями степеней, параметр FactorComplete позволяет указать, следует ли выполнять полное разложение;

• FactorList[poly] — возвращает список множителей полинома poly с их показателями степени, параметр Modulus->p позволяет представить множители полинома по модулю простого р;

• FactorSquareFree[poly] — записывает полином poly в виде произведения множителей, свободных от квадратов, параметр Modulus->p позволяет представить разложение полинома по модулю простого р;

• FactorSquareFreelist[poly] — возвращает список множителей полинома poly, свободных от квадратов, вместе с показателями степени, параметр Modulus->p позволяет представить множители полинома по модулю простого р;

• FactorTerms[poly] — извлекает полный (общий) числовой множитель в полиноме poly;

• FactorTermsList[poly] — возвращает список всех общих числовых множителей полинома poly.

Ниже представлен ряд примеров применения этих функций:

Factor^3-6*х^2+11*х-6]
(-3+х)(-2+х)(-1+х)
Factor[x^3-6*x^2+21*x-52]
(-4+x)(13-2x+x2)
Factor[x^5+8^x^4+31*x^3+80*x^2+94*x+20,Modulus->3]
(1+х)2(2+х)3
FactorList[x^4-1,Modulus->2]
{{1,1},{1+х,4}}
FactorSquareFree[(x^2+1)*(x^4-1)]
(-1+х2)(1+х2)2
FactorTerms[2*x^2+4*x+6]
2(3+2x+x2)
FactorTermsList[2*x^2+4*x+6]
{2,3+2x+x2)
Factorlnteger[123456789]
{{3, 2},{3607,1},{3803,1}}

Функция Factor с параметром Trig->True может работать и с тригонометрическими выражениями:

Factor[Csc[x]+Sec[x],Trig->True]
Csc[x]Sec[x](Cos[x]+Sin[x])
Factor[Sin[3*x],Trig->True]
(1+2*Cos[2*x])Sin[x]

 

Функции для работы с полиномами

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

• Decompose[poly, x] — выполняет разложение полинома poly, если это возможно, на более простые полиномиальные множители;

• GroebnerBasis[{poly1, poly2, ....}, {х1, х2, ...}] — возвращает список полиномов, которые образуют базис Гробнера для идеала, порожденного полиномами polyi;

• PolynomialDivision[p, q, x] — возвращает список частного и остатка, полученных делением полиномов р и q от х;

• PolynomialGCD[poly1, poly2, ...] — возвращает наибольший общий делитель ряда полиномов poly1, poly2,...; с параметром Modulus->p функция возвращает GCD по модулю простого р;

• PolynomialLCM[poly1, poly2, ...] — возвращает наименьшее общее кратное полиномов poly1, poly2, ...; с параметром Modulus->p функция возвращает LCM по модулю простого р;

• PolynomialMod[poly, m] — возвращает полином poly, приведенный по модулю m;

• PolynomialMod[poly, {m1, m2, ...}] — выполняет приведение по модулю всех mi;

• PolynomialQ[expr, var] — возвращает значение True, если expr является полиномом от var, иначе возвращает False;

• PolynomialQ[expr, {var1, ...}] — проверяет, является ли ехрr полиномом от vari;

• PolynomialQuotient[p, q, x] — возвращает частное от деления р и q как полиномов от х, игнорируя какой-либо остаток;

• PolynomialRemainder[p, q, x ] — возвращает остаток от деления р на q как полиномов от х;

• Resultant[poly1, poly2, var] — вычисляет результат полиномов poly1 и poly2 по переменной var; с параметром Modulus->p функция вычисляет результат по модулю простого р.

Следующие примеры поясняют работу с полиномами:

Р[х]:=a*x^3+b*x^2+c*x+d
Q[x]:=e*x^2-f*x-1
Null2
Collect[P[x]+Q[x],x]
-1+d+(c-f )x+(b+e)x2+ax3
Collect[P[x]*Q[x],x]
-d+(-c-df)x+(-b+de-cf )x2+(-a+ce-bf)x3+(be-af )x4+aex5
PolynomialQ[P[x]+Q[x]]
True
Decompose[P[x],x]
{d+cx+bx2+ax3}
PolynomialQuotient[P[x],Q[x],x]

PolynomialRemainder[Q[x],P[x],x]
-1-fx+ex2
CoefficientList[P[x],x]
{d,c,b,a}
Decompose[x^6+x+1-x^3+2*x^5,x]
{1+х-х3+2х56}
PolynomialGCD[P[x],Q[x]]
1
PolynomialLCM[P[x],Q[x]]
P[x]Q[x]
PolynomialQuotient[3*x^3-2*x^2+x,x^2-x+1,x]
1+3x
PolynomialRemainder[3*x^3-2*x^2+x,x^2-x+1,x]
-1-х
Reduce[a*x^2+b*x+c==0,x]

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

 

Средства программирования

 

Виды программирования в системе Mathematica 4

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

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

f[n_]:=n!
f[n_]:=Gamma[n-1]
f[n_]:=n*f[n-1];f[0]=1;f[1]=1;
f[n_]:=Product[i,i,n]
f[n_]:=Module[t=1,Do[t=t*i,i,n];t]
f[n_]:=Module[{t=1},For[i=1,i<=n,i++,t*=i];t]
f[n_]:=Fold[Times,1,Range[n]]

Все их можно проверить по примеру

f[0],f[1],f[5],f[10]
{1,1,120,3628800}

Столь же естественно язык системы реализует ставшее модным в последнее время объектно-ориентированное программирование. В его основе лежат три важнейших понятия: инкапсуляция — объединение в одном объекте как данных, так и методов их обработки; наследование — означает, что каждый объект, производный от других объектов, наследует их свойства, и полиморфизм — свойство, позволяющее передать ряду объектов сообщение, которое будет обрабатываться каждым объектом в соответствии с его индивидуальными особенностями. Приведённый ниже пример объектно-ориентированного программирования дает три определения, ассоциированные с объектом h:

h/:h[x_]+h[y_]:=hplus[x,y]
h/:p[h[x_],x]:=hp[x]
h/:f_[h[x_]]:=fh[f,x]

Средства языка Mathematica позволяют осуществить и визуально-ориентированное программирование. Его смысл заключается в автоматической генерации программных модулей путем указания визуально понятного объекта — чаще всего кнопки. Mathematica позволяет создавать палитры и панели с различными кнопками, предназначенными для управления программой или ввода новых программных объектов. Однако визуально-ориентированное программирование пока не является основным. Достаточно средств язык Mathematica 4 предоставляет и для реализации операторного и процедурного программирования.

 

Задание чистых и анонимных функций

Иногда может потребоваться задание некоторой функции только в момент ее создания. Эта функция представляется только выражением без имени — отсюда и ее название — чистая функция. Для создания такого объекта служит встроенная функция Function[body]. Она создает чистую функцию с телом body. Function [{x}, body] — создает чистую функцию параметра х с телом body и Function[{x1, х2, ,..}, body] — создает чистую функцию ряда параметров х1, х2,... с телом body.

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

Function[{x,n}, х^n]
Function[{x,n}, хn]
%[2,3]
8

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

Function[{x,n}, x^n]
Function[{x, n
}, хn]
{f[2,3],f[z,y]}
{8, zy}

Предельно компактную форму задания функций имеют так называемые анонимные функции. Они не имеют ни названия, ни обычного определения и задаются только выражениями специального вида. В этом выражении вместо переменных используют обозначения # (для одной переменной), #1, #2,... — для ряда переменных. Завершается тело функции символом &. Примеры:

#1^#2&[2,3]
8
#1^#2&[y,z]
УZ

С помощью анонимных функций нетрудно создать функции пользователя:

f[x_,y_]=#1^#2&[x,y]
xy
f[2,3]
8

 

Циклы и рекурсия при функциональном программировании

При функциональном программировании часто требуется суперпозиция функций. Для ее реализации используются следующие функции:

• Nest[expr, x, n] — применяет выражение ехрr к заданному аргументу х n раз;

• NestList[f, х, n] — возвращает список приложений функции f к заданному аргументу х n+1 раз;

• Fold[f, х, list] — возвращает следующий элемент в функции FoldList[f, х, list];

• Foldlist[f, х, {a, b, ...}] — возвращает {х, f[x, a], f[f[x, а], b], ...};

• ComposeList[{f1, f2, ...},х] — генерирует список в форме {х, а[х], а[а[х]], ...}.

Примеры, иллюстрирующие действие этих функций, представлены ниже:

Nest[Exp[x],x,5]
Ех[Ех[Ех[Ех[Ех[х]]]]]
NestList[f,x,3]
{x,f[x],f[f[x]],f[f[f[x]]]}
Fold[f,x,{1,2,3}]
f[f[f[x,1],2],3]
FoldLisy[f,x,{1,2,3}]
{x.f[x,1],f[f[x,1],2],f[f[f[x,1],2]3]}
ComposeList[{Exp,Ln,Sin},x]
{x,Ex,Ln[Ex],Sin[Ln[Ex]]}

Для создания подобия циклов может использоваться функция FixedPoint[f,ехрr]. Она вычисляет выражение ехрr и применяет к нему функцию f, пока результат не повторится. Есть еще одна ее форма, FixedPoint[f, ехрr, SameTest->comp], которая вычисляет ехрr и применяет к нему f, пока два последующих результата не дадут True в тесте. Пример применения функции FixedPoint:

FixedPoint[Function[t,Print[t];Floor[t/2]],27]
27
13
6
3
1
0
0

Последний результат (0) выводится в отдельной (нумерованной) ячейке вывода и означает завершение процесса итераций — деления t на 2. Следующий пример иллюстрирует, как можно создать цепную дробь с помощью функции Nest:

Nest[Function[t,1/(1+t)],у,3]

Еще одна функция такого рода — Catch[expr] — вычисляет expr, пока не встретится Throw[value], затем возвращает value. Одна имеет формы: Catch[expr, form] — вычисляет expr, пока не встретится Throw[value, tag], затем возвращает value, и Catch[expr, form, f] — возвращает f[value, tag] вместо value. Ниже представлены некоторые конструкции циклов с функцией Catch:

Catch[x,a,f]
х
Catch[Throw[х,у], у, fun]
fun[x,у]
Catch[NestList[1/(# + 1)&, -3., 5]]
{-3,-0.5,2.,0.333333,0.75,0,571429}

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

В следующих примерах показано вычисление квадратного корня из числа 5 по известному алгоритму Ньютона, записанному в виде функции newton5:

newton5[x_] := N[1/2(х + 5/х)]
Nest[newton5,1/0,5]
2.23607
NestList[newton5,1/0,5]
{1.,3.,2.33333,2.2381,2.23607,2.23607}
FixedPoint[newton5, 1.0]
2.23607
FixedPointList[newton5, 1.0, SameTest -> (Abs[#1 - #2] < 10.^-4 &)]
{1.,3.,2.33333,2.2381,2.23607,2.23607}

Обратите внимание на то, что функции Nest и FixedPoint дают единственный конечный результат, тогда как функции NestList и FixedPointList возвращают еще и все промежуточные результаты итераций. Последний пример иллюстрирует остановку вычислений по заданной погрешности, равной 10-4.

Далее зададим функцию, реализующую алгоритм Ньютона для нахождения корня произвольного выражения f(х) при начальном значении x0=a по формулам х0=а и

xn=xn-1-f(xn-1)/f'(xn-1)

Эту функцию можно записать следующим образом:

newtoniter[f_,x0_,n_]:=Nest[(#-f[#]/f'[#])&, N[x0],n]

Тогда вычисления корня из выражения ех-2 с начальным приближением х0=0.5 и числом итераций n можно организовать с помощью функций Nest и NestList:

newtoniter[Function[{x},Exp[x]-2.0,0.5,5]]
0.693147
newtoniter[Function[{x},Exp[x]-2.0,0.5,#]&/@Range[5]]
{0.713061,0.693344,0.693147,0.693147,0.693147}
newtoniter1[f_,x0_,n_]:=NestList[(#-f[#]/f'[#])&,N[x0],n]
newtoniter1[Function[{x},Exp[x]-2.0],0.5,5]
{0.5,0.713061,0.693344,0.693147,0.693147,0.693147}

В первом случае возвращается последний результат, а в других — все промежуточные. Функция FixedPoint позволяет осуществлять итерацию до тех пор, пока результат не перестанет изменяться (с машинной точностью). Это иллюстрирует следующий пример:

newtonfp[f_,x0_]:=FixedPoint[(#-f[#]/f'[#])&,N[x0]]
newtonfp[Function[{x},Exp[x]-2.0],0.5]
0.693147

 

Основы процедурного программирования

Процедуры являются полностью самостоятельными программными модулями, задаются своим именем и отождествляются с выполнением некоторой последовательности операций. Они могут быть заданы в одной строке с использованием в качестве разделителя символа ; (точка с запятой):

r=(1+х)^2;r=Expand[r];r-1
2х + х2

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

Для задания процедуры со списком локальных переменных {а, b, ...} и телом рroc может использоваться функция Module[ {а, b, ...}, рroc]. Однако для создания полноценных процедур и функций, которые могут располагаться в любом числе строк, может использоваться базовая структура: Block[{x, у, ...}, procedure] — задание процедуры с объявлением списка локальных переменных х, у,... и Block [{х = х0, у=у0, ...}, procedure] — задание процедуры с объявлением списка переменных х, у,... с заданными начальными значениями. Пример использования базовой структуры:

Q[x]:=Block[{u}.u=(1+x)^2;u=Expand[u]]
g[a+b]
1+2a+a2+2b+2ab+b2
u
u
u=123456;g[2]
9
u
123456

Полезно разобраться со статусом переменной u в этом примере.

 

Управляющие структуры

 

Цикл Do

Хорошо известные циклы Do в Mathematica строятся следующим образом:

• Do[expr, {imax}] — выполняет imax раз вычисление выражения expr;

• Do[expr, {i, imax}] — вычисляет expr с переменной i, последовательно принимающей значения от 1 до imax (с шагом 1);

• Do[expr, {i, imin, imax}] — вычисляет expr с переменной i, последовательно принимающей значения от imin до imax с шагом 1;

• Do[expr, {i, imin, imax, di}] — вычисляет expr с переменной i, последовательно принимающей значения от 1 до imax с шагом di;

• Do[expr, {i, imin, imax}, {j, jmin, jmax}, ...] — вычисляет expr, организуя ряд вложенных циклов с управляющими переменными j, i и т. д.

Примеры организации цикла Do и его исполнения представлены ниже:

• Do[Print["hello"], {5}] — печатает слово hello в пяти строках;

• Do[Print[i], {i, 3}] — печатает в трех строках 1, 2 и 3;

• Do[Print[i], {1,5,8}] — печатает в четырех строках 5, 6, 7 и 8.

• Do[Print[i], {1,0,1,0.25}] — печатает в пяти строках 0, 0.25, 0.5, 0.75 и 1.

Нетрудно убедиться, что переменная i в теле цикла является локальной и по выходе из цикла ее значение остается тем же, что и до входа. Вся программа с циклом является содержанием одной ячейки ввода, и ее листинг охвачен квадратной скобкой. Для иллюстрации вывода здесь использована команда вывода Print в теле цикла. Управляющая переменная цикла может иметь как целочисленные так и вещественные значения. Возможны циклы в цикле (пример ниже):

Do[Do[Print[i,"  ",j,"  ",i+]],{j,1,3},{1,1,3}];
1  1  2
1  2  3
1  3  4
2  1  3
2  2  4
2  3  5
3  1  4
3  2  5
3  3  6

Здесь используются два цикла с управляющими переменными i и j. Командой Print выводятся значения переменных i и j, а также их суммы i+j. Следующий пример иллюстрирует применение цикла Do для задания функции, вычисляющей n-е число Фибоначчи:

fibonacci[(n_Integer)?Positive] :=
Module[fn1 = 1, fn2 = 0,
Do[fn1, fn2 = fn1 + fn2, fn1, n - 1]; fn1]
fibonacci[10]
55
fibonacci[100]
354224848179261915075

Обратите внимание на применение в этом примере функции Module. Она создает программный модуль с локальными переменными (в нашем случае fn1 и fn2), в котором организовано рекуррентное вычисление чисел Фибоначчи.

 

Цикл For

Другой вид циклов — цикл For — реализуется функцией For[start, test, incr, body]. В ней внутренняя управляющая переменная вначале приобретает значение start, затем циклически меняется от этого значения до значения body с шагом изменения incr и так до тех пор, пока условие test не перестанет давать логическое значение True. Когда это случится, то есть test даст False, цикл заканчивается. Пример:

Print["i x"]
For[x=0;i=0;i<4,i++
[x+=5*i,Print[i,"  ",x]]]
i  x
1  5
2  15
3  30
4  50
Return[x] Return[50]

Программа, приведенная выше, позволяет наблюдать за изменением значений управляющей переменной цикла i и переменной х, получающей за каждый цикл приращение, равное 5*i. В конце документа показан пример на использование функции возвращения значений Return[x]. В цикле For не предусмотрено задание локальных переменных, поэтому требуется следить за назначением переменных — при использовании глобальных переменных возможны побочные эффекты.

 

Цикл While

Итак, функция For позволяет создавать циклы, которые завершаются при выполнении какого-либо условия. Такие циклы можно организовать и с помощью функции While[test, expr], которая выполняет выражение expr до тех пор, пока test дает логическое значение True. Ниже дан пример организации и использования цикла While:

i:=1;x:=1;Print["i x"];
While[i<5,i+=1;x+=2*i;Print[i,"  ",N[x]]
1  x
2  5.
3  11.
4  19.
5  29.
Return[x]
Return[29]

Цикл While, в принципе, может заменить другие рассмотренные выше циклы. Однако это усложняет запись и понимание программ. Аппарат локальных переменных в этом типе циклов не используется.

 

Директивы прерывания и продолжения циклов

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

• Abort[ ] — вызывает прекращение вычислений с сообщением $Aborted;

• Break[ ] — выполняет выход из тела цикла или уровня вложенности программы, содержащего данный оператор (возвращает Null — значение без генерации секции выхода);

• Continue[ ] — задает переход на следующий шаг текущего цикла Do, For или While;

• Interrupt[ ] — прерывает вычисления с возможностью их возобновления;

• Return[ ] — прерывает выполнение с возвращением значения Null;

• Return[expr] — прерывает выполнение с выводом значения выражения ехрr;

• Throw[value] — задает прекращение выполнения цикла Catch, если в ходе выполнения выражения ехрr встречается значение value (см. примеры выше).

 

Условные выражения

Как у большинства языков программирования, условные выражения задаются с помощью инструкции или функции If. В системе Mathematica имеются следующие функции If:

• If [condition, t, f] — возвращает t, если результатом вычисления условия condition будет True, и f, если результатом будет False;

• If[condition, t, f, u] — возвращает u, если в результате вычисления условия condition не будет получено ни True, ни False.

Следующий пример поясняет задание программной процедуры с циклом Do, выход из которой задается с помощью функции If и директивы прерывания Aborted[]:

x:=1;Print["i x"];
Do[{If[i==5,Abort[],None],
i+=1;x+=2*i;Print[i,"  ",N[x]]},
{1,1,100}]
1  x
2  5.
3  11.
4  19.
5  29.
$Aborted
Return[x]
Return[1]

 

Функции-переключатели

Для организации ветвления по многим направлениям в современных языках программирования используются инструкции-переключатели. В системе Mathematica множественное ветвление организовано с помощью следующих функций:

• Which[test1, value1, test2, value2, ...] — последовательно вычисляет каждое из выражений testi и, если результат равен True, возвращает соответствующее значение valuei;

• Switch[expr, form1, valuel, form2, value2, ...] — вычисляет выражение ехрr, затем сравнивает его последовательно с каждым значением formi, возвращая то значение valuei, которое соответствует первому совпадению.

Приведем примеры работы этих функций:

Which[1==2,1,2==2,2,3==3,3]
2
Which[1==2,
х,2==2,у,3==3,z]
У
Which[3,1,a,2,b,3,c]
с
Swhich[8,1,a,2,b,3,c]
Swith[8,
      1,  
а,
      
2,  b,
      3,  
с]

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

Switch[8.,1.5,a,2.5,b,8/,с]
с
Switch[1.5,1.5,a,2.5,b,8/,c]
а
Switch[8,1.5, а,2.5,b,8/,с]
Swith[8, 1.5, а,
      2.5, b,
      8., с]

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

 

Безусловные переходы

В Mathematica 4 на всякий случай сохранена инструкция безусловного перехода Goto[tag], которая обеспечивает переход к тому месту программы, которое отмечено меткой Label[tag]. Возможны также формы Goto[expr] и Label[expr]. Применение инструкции Goto иллюстрирует следующий пример:

(q = 2; Label[start]; Print[q]; q += 2;
If[q < 7, Goto[start]])
2
4
6

Интересной особенностью языка программирования Mathematica является возможность создания переходов по значению вычисляемого выражения:

Goto[2+3];
Print["aaaaa"];
Label[2+3];
Print["bbbbbb"]
bbbbb

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

 

Механизм контекстов

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

Чисто внешне контекст задается в виде Имя_контекста'. Апостроф в конце имени и есть признак контекста (он является и разделителем). Один и тот же контекст может принадлежать разным объектам. Например, все системные переменные и встроенные функции имеют контекст System', то есть они относятся к системным объектам, а все символы, вводимые в начале работы с системой, имеют контекст Global' (глобальные).

В системе Mathematica есть средства для визуализации контекстов. Прежде всего это функция Context:

Context[Tan]
System'
Context[E]
System'
Context/@Cos,Pi,Abort
{System',System',System'}

Текущее значение контекста определяет системная переменная $Context иди функция Context[]:

$Context,Context[]
{Global',Global'}

В начале сеанса работы по умолчанию действует контекст Global':

Context/@{q,r,w}
{Global',Global',Global'}

Однако контекст может быть заменен на любой нужный пользователю, например:

{new'q,new'w,Global'r}
{new'q,new'w,r}
Context/@new'q,new'w,Global'r
{new',new',Global'}

Обратите внимание на то, что символы new'q и new'wq'х имеют свой новый контекст new' и отображаются вместе с ним (но контекст указан перед символом). А вот символ Global' r отображается лишь кратким именем. Причина этого в том, что текущий контекст есть Global', а контекст new отсутствует на так называемой контекстной дорожке, проще говоря, списке контекстов. Что касается символов q, r и z, то сами по себе (без новой контекстной приставки) они по-прежнему имеют контекст Global':

Context/@{q,r,w}
{Global',Global',Global'}

Для вывода контекстной дорожки используется переменная $ContextPath:

$ContextPath
'{Graphics'Animation', Global', System'}

С помощью функции Prepend можно добавить в контекстную дорожку новый контекст, например new':

$ContextPath=Prepend[$ContextPath,"new'"]
{new'.Graphics'Animation'.Global',System'}

Теперь функция Context возвращает только контексты символов new'q, new'w и Global'r:

Context/@new'q,new'w,Global'r
{new',new'.Global'}

С помощью функции Begin можно изменить текущий контекст на заданный, например Global' на new':

Begin["new'"]
new'
q=5;
{q,Context[q]}
{5,new'}

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

Для получения списка всех определений с заданным контекстом можно использовать функцию Name["Context'S"], где — символ (или строка), определяющий имена определений. Например, для получения всех определений с контекстом System' можно использовать функцию Name["System'*].

Функция Name[] без параметра выводит полный список всех определений как для ядра, так и для пакетов расширений с указанием их контекстов. Таким образом, данная функция позволяет получить самую полную информацию об определениях (функциях, константах и т. д.), которые имеет текущая версия системы Mathematica.

 

Типовая структура пакетов расширения

Структура пакета расширений в минимальном виде выглядит следующим образом:

(*Вводный комментарий*)
BeginPackage["Имя_пакета'"]
Mean::usage = "Имя функции[Параметры] Текстовый комментарий"
............................................................
Begin["'Private'"]
Unprotected
[Список_имен]
Определения новых функций
End[ ]
Установка атрибутов защиты
EndPackage[ ]
(*Завершающий комментарий*)

Приведем пример простого фрагмента программы, дающего определение новой функции ExpandBoth с помощью некоторых из представленных средств:

(* :Title: ExpandBoth *)
(* :Context: ProgrammingInMathematica'ExpandBoth' *)
(* :Author: Roman E. Maeder *)
ExpandBoth::usage = "ExpandBoth[e] expands all numerators and
denominators in e."
Begin["'Private'"]
ExpandBoth[x_Plus] := ExpandBoth /@ x
ExpandBoth[x_] := Expand[Numerator[x]] / Expand[Denominator[x]]
End[]
Null

Ниже представлен сеанс работы с этим пакетом, файл которого expboth.m размещен в подпапке mypack общей папки пакетов расширений:

<<mypack\expboth.m
?ExpandBoth
ExpandBoth[e] expands all numerators and denominators in e.
ExpandBoth[124/12]

ExpandBoth[1234/12]

В практике подготовки и отладки программ важное значение имеет наличие специальных средств отладки программ по шагам — средств трассировки. Функция Тrасе[ехрr] позволяет выполнить трассировку выражения ехрr. Возьмем простой пример — вычисление выражения 2*(3+4)2/5:

Тrасе[2(3+4)2/5]

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

Теперь рассмотрим, как выглядит пакет расширения, решающий систему ДУ хорошо известным численным методом Рунге—Кутта четвертого порядка. Ниже представлена распечатка данного пакета:

(* :Title: RungeKutta *)
(* :Context: ProgrammingInMathematica'RungeKutta' *)
BeginPackage["ProgrammingInMathematica'RungeKutta'"]
RKSolve::usage =
    "RKSolve[{e1,e2,..}, {y1,y2,..}, {a1,a2,..}, {t1, dt}]
    numerically integrates the ei as functions of the yi with inital
    values ai.The integration proceeds in steps of dt from 0 to t1.
    RKSolve[{e1,e2,..}, {y1,y2,..}, {a1,a2,..}, {t, t0, t1, dt}]
    integrates a time-dependent system from to to t1."
Begin["'Private'"]
RKStep[f_, y_, y0_, dt_] :=
Module[{ k1, k2, k3, k4 },
    k1 = dt N[ f /. Thread[y -> y0] ];
    k2 = dt N[ f /. Thread[y -> y0 + k1/2] ];
    k3 = dt N[ f /. Thread[y -> y0 + k2/2] ];
    k4 = dt N[ f /. Threadty -> y0 + k3] ];
    y0 + (k1 + 2 k2 + 2 k3 + k4)/6
  ]
RKSolve[f_List, y_List, y0_List, (t1_, dt_}] :=
    NestList[RKStep[f, y, #, N[dt]]&, N[y0], Round[N[t1/dt]]] /;
    Length[f] == Length[y] == Length[y0]
RKSolve[f_List, y_List, y0_List, {t_, t0_, t1_, dt_}] :=
    Module[{res},
    res = RKSolve[Append[f,1],Append[y,t],Append[y0,t0],{t1-t0,dt}
];
Drop[#, -1]& /@ res /; Length[f] == Length[y] == Length[y0]
End[]
Protect[ RKSolve ]
EndPackage[]

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

<<mypack\rk4.m
RKSolVe[{t*y+z,t+y*z}
,{у,z},{1,1},{t,1,1.5,0.1}]
{{1.,1.},{1.22754,1.22844},{1.52241,1.53202},
{1.90912,1.95373},{2.42456,2.77444},{3.12741,3.55937}}

Решение представлено списком значений {yi,zi}, определяющим зависимости у(t) и z(t). Этот пример хорошо иллюстрирует реализацию популярного численного метода для решения систем ДУ.