Тихон Тарнавский

система символьной математики

команда в Максиме завершается точкой с запятой

-   +   *   /   ** или ^   sqrt()

(%i2) 3 + 4 ;
(%o2)                                  7
(%i3) _ + 6 ;
(%o3)                                 13

каждая ячейка имеет свою метку — заключенное в скобки имя ячейки. ячейки ввода именуются как %i с номером (i от input — ввод), ячейки вывода — как %o с соответствующим номером (o от output — вывод). со знака % начинаются все встроенные служебные имена. внутренними именами %e и %pi обозначены математические постоянные; а через %c с номером обозначаются константы, используемые при интегрировании

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

последняя ячейка вывода обозначается % , а последняя ячейка ввода _

вывод результата вычисления можно заглушить, завершив команду символом $ вместо ;

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

(%i4) eq: x^3 - x ;
                                     3
(%o4)                               x  - x

имя name можно очистить от присвоенного ему выражения и освободить занимаемую этим выражением память. для этого нужно просто набрать kill(name) . можно очистить разом всю память и освободить все имена, введя kill(all)

в Maxima есть специальная функция — describe() , которая выдает информацию из документации по конкретным словам. существует сокращенная версия вызова этой функции: ? name

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

точкой . обозначается матричное произведение

(%i5) a : [1,2,3] ;
(%o5)                              [1, 2, 3]
(%i6) a . a ;
(%o6)                                 14

entermatrix (m, n)
Returns an m by n matrix, reading the elements interactively

matrix (row_1, …, row_n)
Returns a rectangular matrix which has the rows row_1, …, row_n
Each row is a list of expressions
All rows must be the same length

copymatrix (M)
Returns a copy of the matrix M
This is the only way to make a copy aside from copying M element by element


ident (n)
Returns an n by n identity matrix

zeromatrix (m, n)
Returns an m by n matrix, all elements of which are zero



rank (M)
Computes the rank of the matrix M

determinant (M)
Computes the determinant of M

mattrace (M)
Returns the trace of the square matrix M

permanent (M)
Computes the permanent of the matrix M by the Johnson-Gentleman tree minor algorithm
A permanent is like a determinant but with no sign changes
permanent returns the result in CRE form



col (M, i)
Returns the i'th column of the matrix M as a matrix

row (M, i)
Returns the i'th row of the matrix M as a matrix

addrow (M, list_1, …, list_n)
Appends the row(s) given by the one or more lists (or matrices) onto the matrix M

addcol (M, list_1, …, list_n)
Appends the column(s) given by the one or more lists (or matrices) onto the matrix M



transpose (M)
Returns the transpose of M

invert (M)
Returns the inverse of the matrix M

все функции и операторы Maxima работают не только с действительными, но и комплексными числами. комплексные числа записываются в Максиме в алгебраической форме, с мнимой единицей, обозначенной через %i; то есть в виде a+b*%i

оператор задания функции обозначается через :=

(%i10) func1 (x) := x + 2 ; 
(%o10)                         func1(x) := x + 2
(%i11) func1 (12) ;
(%o11)                                14

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

(%i13) '' 1  + 2 ;
(%o13)                                  3
(%i14) ev(4 + 7) ;
(%o14)                                 11
(%i15) 12 + 78, simp ;
(%o15)                                 90

точно так же, как двойной апостроф — сокращение для ev() без дополнительных опций, есть еще более упрощенная запись функции ev() с опциями: в этом случае вместо имени функции и скобок вообще ничего писать не нужно, т.е. ev(выражение,опц1,опц2,…) можно записать просто как «выражение,опц1,опц2,…»

первая из таких опций связана с автоупрощением. глобально автоупрощение регулируется переключателем simp (от simplification), и по умолчанию оно включено; в любой момент его можно выключить, установив значение переключателя в false. опция функции ev, одноименная этому переключателю, позволяет включить упрощение для данного конкретного вычисления — вне зависимости от того, включено или выключено оно глобально

функция rat(выражение) преобразовывает рациональное выражение к канонической форме (Canonical Rational Expression, CRE), то есть раскрывает все скобки, затем приводит все к общему знаменателю, суммирует и сокращает; кроме того, приводит все числа в конечной десятичной записи к рациональным. это удобно, если вам нужно пошагово проделать большое количество рациональных преобразований: вы можете, один раз вызвав rat() , ссылаться на предыдущие ячейки и далее видеть на каждом шаге итоговое выражение в канонической форме. если на каком-то этапе такое поведение станет вам мешать, вы можете вернуть выражение из канонической к общей форме с помощью функции ratdisrep(выражение) . каноническая форма автоматически отменяется и в случае любых преобразований, не являющихся рациональными

решение уравнений

solve (expr)
solve (expr, x)
solve ([expr1, ..., eqxpn], [x1, ..., xn])

решает уравнение expr для переменной x, которое может быть опущено, если х - единственная переменная в уравенении

(%i16) solve(eq) ;
(%o16)                       [x = - 1, x = 1, x = 0]

(%i17) a:%pi/4 $ b: %pi/2 ;
                                      %pi
(%o17)                                ---
                                       2

дифференцирование

(%i18) diff(eq,x) ;
                                       2
(%o18)                              3 x  - 1

функция diff принимает один либо два аргумента. с двумя, diff(выражение, переменная), она возвращает производную от «выражения» по заданной переменной; с одним, diff(выражение) — полный дифференциал заданного выражения. запись diff(f, x) равнозначна математическому обозначению df/dx, а diff(f) равнозначна df

интегрирование

функция интегрирования называется integrate и имеет два варианта вызова: для нахождения неопределенного и определенного интегралов. первый выглядит как integrate(выражение, переменная), второй — как integrate(выражение, переменная, нижний-предел, верхний-предел)

(%i26) integrate (sin(x),x,a,b) ;
                                       1
(%o26)                              -------
                                    sqrt(2)

кроме определенных интегралов Maxima умеет искать также и несобственные интегралы, то есть такие, у которых неограничена либо область интегрирования, либо подынтегральная функция; и делается это все той же функцией integrate

(%i27) integrate(1/(sqrt(x)), x, 0, 1) ;
(%o27)                                   2

пределы

полноценных функций для нахождения предела существует в Maxima аж одна, но зато какая! она может принимать три различных варианта списка аргументов, и кроме того, на ее действие влияют еще и три флага. зовут эту функцию limit ; и в самом стандартном варианте ее вызов выглядит как limit(выражение, переменная, точка)

(%i29) limit ((x^2 - 1) / (2*x^2-x-1) , x , 1) ;
                                       2
(%o29)                                 -
                                       3
    

Maxima может искать пределы не только в конечных точках, но и на бесконечности. среди стандартных обозначений программы существуют универсальные названия для разных бесконечностей: плюс-бесконечность записывается через inf (от слова infinity), минус-бесконечность — через minf (от minus infinity); для комплексных чисел бесконечность, как известно, одна, и она (комплексная бесконечность) обозначается полным словом infinity

второй вариант вызова функции limit() — это расширенная версия первого: limit(выражение, переменная, точка, направление), для поиска односторонних пределов. для предела справа в качестве «направления» указывается plus, для предела слева — minus. кроме упомянутых выше бесконечностей, на выходе возможно появление и еще двух обозначений, на случай, если заданный предел не существует: ind (от слова indefinite — неопределенный) и und (от слова undefined — опять же неопределенный)

функция limit() в третьем варианте — limit(выражение) — предназначена уже не для поиска собственно пределов, а для упрощения выражений, содержащих символы inf и minf

(%i35) limit(1/inf) ;
(%o35)                                 0

ветвление

в Maxima связка if-then-else является не синтаксической конструкцией, а оператором. по своему действию он больше всего похож на тернарный оператор языка C, только с более «человеческим» синтаксисом: if условие then выражение1 else выражение2. при выполнении «условия» из двух «выражений» вычисляется только первое и возвращается как результат оператора; в противном случае выполняется только второе и оно же является значением всего выражения if-then-else . часть конструкции else выражение2 опциональна. если ее нет, а условие все-таки не выполнилось, результат оператора if будет равен false

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

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

условия >, <, >=, <= записываются и расшифровываются традиционно, так же как и логические операторы and, or, not , а вот о равенствах-неравенствах нужно сказать пару слов. равенство в Maxima есть двух видов: синтаксическое и логическое. знаком = обозначается как раз первое, а второе вычисляется с помощью функции equal() . дополнительно используется предикат по имени is , которые проверяет на истинность свой аргумент

ну и неравенств, соответственно, тоже существует два. синтаксическое неравенство обозначается достаточно непривычно — через #; видимо, этот символ разработчики сочли наиболее визуально схожим со знаком ≠. ну а логическое неравенство обозначено через notequal()

в условном операторе можно использовать любые предикаты, то есть функции, возвращающие логические значения true/false

итерация

цикл в Maxima тоже один, но он имеет столько различных вариантов, что назвать это все одним оператором цикла язык не поворачивается. вот как выглядят основные разновидности:

for переменная:начало step шаг thru конец do выражение
for переменная:начало step шаг while условие do выражение
for переменная:начало step шаг unless условие do выражение

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

второй — от начала и пока выполняется условие

третий — наоборот, пока условие не выполняется

шаг может быть опущен и по умолчанию равен единице. самое интересное в этом операторе то, что опустить позволяется любую его часть, кроме do; и в том числе в любых комбинациях. к примеру, опустив кроме step еще и for, мы получаем из этого же оператора традиционные циклы while и unless (второй и третий варианты). а проделав то же самое с первым вариантом записи, получим цикл без счетчика вида thru число do выражение, который просто повторится заданное число раз. можно, наоборот, опустить условие окончания и получить цикл с индексной переменной, но бесконечный. а оставив только do, получим самый простой вариант бесконечного цикла. из таких бесконечных циклов можно выйти с помощью оператора return(выражение) (точнее, конечно, конструкции из двух операторов вида if условие then return(выражение)), который прервет выполнение цикла и вместо done вернет заданное выражение. естественно, оператор return() можно применять во всех видах циклов, а не только в бесконечных

кроме всех уже рассмотренных вариаций, цикл может принимать еще две ипостаси

во-первых, вместо step может использоваться конструкция next выражение

после next может стоять любое вычислимое выражение относительно индекса цикла, и применяться эта конструкция может во всех трех вариантах цикла (thru/while/unless)

а «во-вторых» — это еще один отдельный вариант цикла: for переменная in список do выражение; либо расширенная форма: for переменная in список условие do выражение

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

графики

количество различных функций в Maxima разработчики постарались свести к минимуму, а широту размаха каждой конкретной функции, соответственно, к максимуму. соблюдается эта тенденция и в функциях построения графиков: основных таких функций всего две, с очевидными, как всегда, названиями — plot2d и plot3d. возможности графической отрисовки не встроены в Maxima, а реализованы посредством внешних программ, в чем и прослеживается пресловутый Unix-way: «одна задача — одна программа». по умолчанию, построением графиков занимается gnuplot

функция plot2d. кратчайший вариант ее вызова такой: plot2d(выражение, [символ, начало, конец]), где выражение задает функцию, график которой нужно построить, символ — неизвестное (он, понятное дело, должен быть единственным неопределенным символом, входящим в выражение), а начало и конец задают отрезок оси Х для построения графика; участок по оси Y в таком варианте записи выбирается автоматически, исходя из минимума и максимума функции на заданном промежутке. обратите внимание, что неизвестное и концы промежутка нужно задавать не тремя отдельными параметрами, как, скажем, в integrate, а в виде списка. это связано с тем, что plot2d может принимать еще и дополнительные аргументы — в таком случае они перечисляются следом за таким списком, что исключает всякую путаницу

(%i38) plot2d(x*cos(x),[x,-2*%pi, 2*%pi]) $

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

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

для этого предусмотрен такой вариант вызова функции:

plot2d(выражение, [символ, начало, конец], [y, начало, конец])

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

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

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

plot2d([discrete, x-список, y-список])
plot2d([discrete, [x, y]-список])

в первом варианте координаты задаются как два отдельных списка [x1, x2, …, xn], [y1, y2, ,…, yn], а во втором — как список пар координат отдельных точек [[x1, y1], [x2, y2], …, [xn, yn]]. если мы, к примеру, имеем набор статистических значений, зависящих от номера, мы можем отобразить его, задав в качестве x-координат сами эти номера, то есть натуральные числа

функция plot3d имеет два варианта вызова: один для явного задания функции и один для параметрического. в обоих случаях функция принимает три аргумента. для явно заданной функции: plot3d(выражение, [переменная1, начало, конец], [переменная2, начало, конец]); аргументы аналогичны plot2d, с той разницей, что здесь независимых переменных две

файлы

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

функции чтения файлов с выражениями Maxima существует три: demo(имя-файла), batch(имя-файла) и batchload(имя-файла)

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

функция batch() загружает Maxima-файл с расширением .mac или .mc и выполняет содержащиеся в нем выражения так, как если бы они вводились прямо в текущей сессии, то есть с отображением результата каждого выражения и назначением меток %iN, %oN

функция batchload() , напротив, подгружает пакетный файл «молча»: все назначенные в нем функции и переменные становятся доступны, но результаты не видны, и весь хранимый ввод-вывод, включая значения символов % и _ и результаты, возвращаемые функцией %th(), остается тем же, что и до вызова

теперь перейдем к записи. тут нас в первую очередь интересует функция stringout() , которая позволяет выгружать в файл любые выражения и функции Maxima в точно таком виде, в каком их загружают функции demo(), batch() и batchload() . с ее помощью можно писать выражения, которые вы хотите иметь во внешнем модуле, находясь непосредственно в интерфейсе Maxima, с последующей записью в этот самый модуль. для выгрузки функций в один из стандартных каталогов имя файла во всех вариантах вызова функции stringout() нужно задавать с полным путем; в случае задания имени без пути файл будет создан в текущем каталоге, то есть в том, откуда производился запуск Maxima

stringout() может принимать несколько различных вариантов аргументов, первым из которых всегда выступает имя файла для записи, а остальные отвечают за то, что же именно будет туда записано. в варианте stringout(имя-файла, [начало, конец]) записаны будут ячейки ввода с номерами от «начала» до «конца» включительно

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

функцию stringout() можно вызвать с непосредственным перечислением в аргументах конкретных выражений. в этом случае будут сохраняться не ячейки, содержащие заданные выражения, а именно сами выражения. то есть, если перечислить символ, для которого задано значение, то в файл будет записано только это значение. с именами функций, заданными непосредственно, дело обстоит не лучше: функцию таким образом задать, по сути, вообще нельзя: если просто написать ее имя, то вместо функции будет подставлен одноименный символ (или его значение, если оно задано). но из ситуации есть выход. для функций — штатный: функция fundef , которая принимает имя любой пользовательской функции и возвращает ее определение в точности в таком же виде, в каком оно было введено (или могло бы быть введено) в командной строке Maxima, с точностью до пробелов