Человеческая память для меня загадка. Являясь обладателем слабой памяти с детства, вечно забываю о некоторых нюансах окружающего меня мира. Тем не менее, эти данные должны быть под рукой. И когда не хватает блокнота, на помощь приходят текстовые файлы. Один из таких файлов содержит небольшую сборку повседневных и обыденных команд Maximа.
Я думаю, всем из нас известна данная система компьютерной алгебры. Она не является конкурентом Wolfram Mathematica, но она обладает именно тем функционалом, который я требую от математического софта. Если говорить проще и доступнее — считать можно на всём, от палочек до суперкомпьютеров, и далеко не всегда задачи инженерной практики целиком переносятся с бумаги в программный код. Одним из примеров, который я честно говоря, еле-еле застал, является сегодня забытая поделка нашего конверсионного производства — цельнометаллический бытовой вакуумный гражданский термос, который выпускался ранее ещё в СССР на Урале. Чтобы наладить его производство институт, в котором я учусь, де-факто вручную на счётных машинках высчитал все необходимые параметры рабочего оборудования. Поэтому лицензия на Mathematica — не показатель и не ценз пригодности к практике. Считать, повторюсь, можно на всём.
От слов к делу. Ниже разбиты на категории те моменты в документации Maxima, которые желательно знать для начинающего пользователя данной СКА.
Общий функционал
- % — последняя ячейка вывода (т. е. значение, полученное в результате последнего вычисления);
- _ — последняя ячейка ввода (т. е. повтор последней введенной команды);
- %oN — результат вычисления с номером N (например, %o15)
- %iN - повторить ввод (повторить введенную ранее команду с номером N, например %i25)
- %th(N) — возвращает N-ю с конца ячейку вывода;
- $ — глушение вывода результата;
- ** или ^ — возведение в степень;
- kill(all) — очистить сеанс;
- describe(name) или? name — помощь по конкретным словам;
- example(name) — пример использования;
- demo() — выполняет программы из демонстрационных файлов, поставляемых с системой;
- 'выражение — предотвращает вычисление выражения;
- ''выражение — аналог ev (принудительное вычисление выражения);
- num(%) — числитель дроби;
- denom(%) — знаменатель дроби;
- coeff(n,x,3) — возвращает коэффициент при переменной в заданной степени;
- depends([m,y],[x,z]) — устанавливает зависимость m(x,z) и y(x,z);
- second(y = 14) — извлечёт 14;
- subst — подстановка одного выражения в другое;
- changevar (%, x — 3 — y ,y ,x); — замена переменных в выражении;
- %, y=x-3 — обратная подстановка;
- float(%) — преобразовать к вещественной форме;
- nouns(%) — раскрывает вообще все несовершённые формы – и производные в том числе;
- eval – напротив, проводит дополнительно ещё один процесс вычисления. в выражения тоже могут входить некоторые символы, которые тоже могут иметь свои значения; и такая цепочка «вложенных значений» может продолжаться сколь угодно глубоко. Один вызов функции ev (без опции eval) опускается по этой цепочке в глубину на один уровень: noeval блокирует сам этап вычисления как таковой; т.е. её можно использовать для того, чтобы применить к выражению другие опции функции ev, не перевычисляя его;
- lhs(eq) — rhs(eq) — левая и правая части некоторого выражения;
- eliminate([x+y+z=1,x+y=2,x+z=3],[z]) — исключить из системы уравнений переменную или несколько переменных, то есть уменьшить размерность системы;
- gcd(420,1176) — НОД;
- mod(x,y) — остаток от деления x на y со знаком x;
- signum(x) — вернёт +1 если x >0, -1 если x <0;
- max/min;
- log(x) — НАТУРАЛЬНЫЙ логарифм («ln(x)»);
- floor(4.445) — округление вниз;
- ceiling(4.445) — округление вверх;
- listofvars(%) превращает исходное выражение в список содержащихся в нем переменных;
- numer:true (или numeric:true) — проведение расчётов только с плавающей точкой, а не с рациональными числами;
- bindtest — запрещает использовать символ в выражениях до присвоения ему значения;
- batch() загружает Maxima-файл с расширением .mac или .mc (от первоначального названия программы – Macsyma) и выполняет содержащиеся в нем выражения.
- batchload(), подгружает пакетный файл «молча»: все назначенные в нем функции и переменные становятся доступны, но результаты не видны, и весь хранимый ввод-вывод, включая значения символов % и _ и результаты, возвращаемые функцией %th(), остается тем же, что и до вызова.
- file_search_maxima — переменная, содержащая каталоги пользовательских файлов и файлов самой СКА;
- ~/.maxima — стандартный каталог системы;
- file_search_lisp и file_search_demo — функции для поиска соответствующих файлов;
- load() — обертка над двумя функциями загрузки файлов, просто короче;
- loadfile() -загружает файл с исходным кодом Lisp (парна к save());
- stringout()- выгружает в файл любые выражения и функции Maxima;
- declare() — внести факт в базу фактов;
- facts(name) или facts() — узнать текущее состояние базы;
- remove() — удалить свойства из базы;
- assume() — в качестве аргументов принимает в любом количестве самые обыкновенные равенства и неравенства в логической форме, то есть не «a=b», «a#b», а «equal(a,b)», «not equal (a,b)». Из логических операторов допускается также использование and (по сути assume(x>0 and x<1) это то же самое, что и assume(x>0, x<1)), но не or – база фактов не поддерживает информацию вида «или»; и речь не о синтаксисе, а именно о конструкциях, то есть выражения типа not(a>b and a<c) тоже недопустимы. Факты, добавленные assume(), также видны функции facts():
Производные, пределы, ряды...
- diff(выражение) — находит полный дифференциал выражения, который является суммой всех частныхпроизводных по переменным выражения;
- diff(выражение, переменная) — находит частную производную первого порядка;
- diff(выражение, переменная, N) — находит частную производную N-го порядка;
- diff(выражение, х_1, N_1, х_2, N_2, …) —находит сумму частных производных;
- derivlist(x, y, ..., v) – производные относительно переменных, заданных в качестве аргументов, а также полные дифференциалы (так как они не зависят ни от каких переменных);
- integrate(%,x) — интегрирование;
- romberg(cos(sin(x+1)), x, 0, 1) — численное интегрирование методом Ромберга;
- limit ((x^2 — 1)/(x^2 + 1), x, inf) — вычисление пределов;
- limit ((x^2 — 1)/(x^2 + 1), x, minf);
- limit (tan(x), x, %pi/2, plus) — предел справа;
- limit (tan(x), x, %pi/2, minus) — слева;
- tlimit(...) — попытка найти предел с поднятым флагом tlimswitch (см. ниже);
- sum(i, i, 1, 100) — сумма ряда;
- product — произведение ряда (синтаксис аналогично sum);
- sum(1/x^2, x, 1, inf), simpsum=true; — чтобы выполнить суммирование, нужно указать опцию «simpsum=true»;
- sumcontract(sum1+sum2) — сокращение сум;
- taylor(sin(x), x, 0, 8) — ряды;
- niceindices(powerseries(sin(x), x, 0)) — ряды с упрощением;
Упрощения
- simp: false — отключить принудительное упрощение «на лету»;
- ratdenomdivide — по умолчанию системная переменная имеет значение «true». В этом случае каждая дробь, в которой числитель является суммой, раскладывается на сумму дробей с одинаковым знаменателем. Если же присвоить этой опции значения «false», то тогда все дроби с одинаковым знаменателем будут объединены в одну дробь с числителем в виде суммы числителей начальных дробей;
- expand() — раскрыть скобки, упростить;
- distrib() – expand(), но только на один уровень в глубину;
- combine() — функция, собирающая воедино дроби с одинаковыми знаменателями;
- trigsimp(%) — тригонометрические упрощения через основное тригонометрическое тождество;
- trigrat(%) — аналогично, посильнее;
- trigreduсe(%) — преобразовать тригонометрические выражения в канонические конечные тригонометрические ряды (Fourier sums) [преобразует тригонометрическое выражение как сумма слагаемых, каждое из которых содержит один синус или косинус];
- trigexpand(%) — «раскрывает» аргументы тригонометрических функций, согласно правилам тригонометрических функций от суммы углов;
- partfrac(%) — разложение на простые дроби;
- ratsimp(%) — быстро упростить сумму рациональных выражений;
- fullratsimp(выражение) — последовательно применяет к выражению функцию ratsimp, а также некоторые нерациональные преобразования и повторяет эти действия в цикле до тех пор, пока выражение не перестанет в процессе преобразования изменяться (медленнее, зато дает более надежный результат);
- ratexpand(%) — приводит дроби к общему знаменателю;
- radcan(%) — «сократить» экспоненты с логарифмами, перейдя к каноническому радикалу [упрощение показательных, логарифмических и степенных (с рациональными степенями) функций];
- factor — максимально сворачивает выражение в скобки;
- factorsum() — если многочлен не может быть представлен в виде произведения нескольких сомножителей, его можно попытаться преобразовать в сумму таких произведений;
- 0. Также имеются такие функции как: atensimp, foursimp, fullratsimp, logarc, rootscontract, scsimp, simplify_sum, vectorsimp.
- 1. После ratexpand() и в числителе, и в знаменателе дроби все скобки будут раскрыты, в случае же rat() слагаемые, где имеются, например, две переменные, будут сгруппированы, и одна из них будет вынесена за скобки.
- 2. expand раскрывает скобки на всех уровнях вложенности, а ratexpand раскрывает рациональное выражение только первого уровня, при этом подвыражения, которые не являются рациональными, не обрабатываются;
- 3. ratexpand приводит дроби-слагаемые к общему знаменателю, а expand этого не делает;
- 4. На expand не влияет системная опция ratdenomdivide;
- 5. expand не преобразует в рациональные числа конечную десятичную запись независимо от значения системной опции keepfloat.
- 6. maxposex и maxnegex — переменные, управляющие раскрытием возведения в целую степень — максимальные положительный и отрицательный показатель степени, которые будут раскрываться этой функцией expand ( По умолчанию 1000), переназначить можно прямо в функции expand();
- 7. expop и expon — переменные, задают максимальные положительную и отрицательную степени, которые будут раскрываться автоматически, без вызова функций группы expand (по умолчанию 0, то есть автоматически степени не раскрываются вообще);
- 8. Флаг – halfangles – управляет раскрытием формул половинных углов;
- Два флага – trigexpandplus и trigexpandtimes – отвечают соответственно за применение формул сумм углов и кратных углов (по умолчанию установлены);
- 9. Флаги trigsign и triginverses — первый принимает традиционные два значения (по умолчанию – true) и регулирует вынос знака за пределы тригонометрической функции. Флаг triginverses – трехзначный, и умолчательное его значение равно all. Он отвечает за обработку сочетаний вида sin(asin(x)) или atan(tan(x)). Значение all позволяет раскрывать эти сочетания в обоих направлениях (напомню, что при этом часть корней будет теряться); значение true оставляет разрешенным раскрытие только вида sin(asin(x)), то есть блокирует вариант с потерями периодических значений; а случай false запрещает оба направления преобразований;
- 10. Флаг tlimswitch. По умолчанию он тоже выключен, а если его включить, функция limit будет, при невозможности найти предел другими способами, пытаться его найти путем разложения подпредельной функции в ряд Тейлора в окрестности заданной точки;
- 11. Единственный флаг, имеющий прямое отношение к самой функции diff – это флаг derivabbrev, который влияет на отображение производных в ячейках вывода Maxima. По умолчанию он равен false, и производные обозначаются в виде дробей с буквой d; если же его выставить в true, производные будут отображаться в сокращенном виде, с переменными дифференцирования записанными в виде индексов.
- 12. solveradcan — флаг, по умолчание false, а выставив этот флаг в true, мы заставим solve применять radcan, что в некоторых случаях может помочь разрешить проблемы, которые без этого ключа приведут к невозможности найти точное решение.
Матрицы
- A: matrix([1,2],[3,4]);
- Определитель матрицы. Функция determinant(matrix).
- Транспонирование матрицы. Функция transpose(matrix).
- Вычисление обратной матрицы. Функция invert(matrix).
- Построение характеристического многочлена матрицы. Функция charpoly(matrix, var).
- Сложение матриц (знак «+»). Почленно складывает все элементы двух матриц.
- Вычитание (знак «-»). Совершенно аналогичен сложению, но элементы матриц вычитаются.
- Деление матриц (знак «/»). Деление слабо отличается от сложения, каждый элемент одной матрицы делится на соответствующий элемент другой матрицы.
- Перемножение матриц почленно (знак «*»). Этот оператор работает также как и сложение: элементы первой матрицы умножаются на соответствующие элементы второй матрицы. Это не то умножениематриц, которое обычно подразумевается в курсе линейной алгебры!
- Умножение матриц (знак «.», точка).
- addcol(V1,[9,10]) — добавление столбца к матрице;
- addrow(V1,[9,10]) — добавление строки к матрице;
- V1: submatrix(V1, 6,7) — удалить из матрицы V1 6-й и 7-й столбец;
- submatrix(начальный номер удаляемой строки, конечный номер удаляемой строки; Имя
- матрицы;) — уменьшение количества строк;
- M[j, i] — обращения к конкретному элементу массива М;
- zeromatrix(m, n) — создание нулевой матрицы размерностью m*n;
- ident(n) — создание единичной квадратной матрицы;
- diagmatrix(n, x) — создание диагональной квадратной матрицы размерностью n*n;
- transpose(M) — транспонирование матрицы M;
- matrix_size(M) — определение количества столбцов и строк матрицы;
- rank(M) — определение ранга матрицы;
- mattrace(M) — определение следа (суммы диагональных элементов) квадратной матрицы (* приложению предшествует загрузка пакета для работы с матрицами: load («nchrpl»));
- determinant(М) — вычисление определителя (детерминанта) квадратной матрицы;
- invert(M) -вычисление матрицы, обратной к М.
Обыкновенные дифференциальные уравнения
1)
ode2(уравнение, функция, переменная). Функцией обычно является у, а переменной — х;
Помимо решения дифференциального уравнения в общем виде, можно решать уравнения с начальными условиями (краевая задача). Для этого необходимо решить уравнение в общем виде при помощи функцииode2, а затем воспользоваться одной из функций поиска начальных условий:
- ic1(решение, точка х, значение у в точке х) —для решения дифференциальных уравнений 1-го порядка с начальным условием;
- ic2(решение, точка х, значение у в точке х, значение y' в точке х) — для решения дифференциальных уравнений 2-го порядка с начальным условием;
- bc2(решение, точка х1, значение у в точке х1, точка х2, значение у в точке х2) — для решения дифференциальных уравнений 2-го порядка с начальными условиями в виде двух точек;
2)
desolve(дифференциальное уравнение, переменная);
Если осуществляется решение системы дифференциальных уравнений или есть несколько переменных, то уравнение и/или переменные подаются в виде списка:
desolve([список уравнений], [переменная1, переменная2,...]);
Так же как и для предыдущего варианта, для обозначения производных в дифференциальных уравнениях используется функция diff, которая имеет вид 'diff(f(x), x);
atvalue(функция, переменная = точка, значение в точке) — начальные значения.
Графики
plot2d(sin(x), [x,0,6]);
plot2d(sin(x), [x,0,1], [y,0,1]);
plot2d([parametric, realpart(W(%i*t)), imagpart(W(%i*t))], [t,0,100], [nticks,1000])$
Параметрические графики строятся так:
[parametric, x(t), y(t)]
Поэтому из приведенной формулы были подставлены параметрические функции. Далее, [t,0,100] — это диапазон точек, в котором рисовать годограф. Тут у каждого получается по-разному, ясно, что кривая уходит либо в 0, либо в бесконечность, тут главное не переборщить. Рекомендуется поиграться с диапазоном значений t, чтобы определить откуда и куда движется кривая. Данный пример берёт начало в точке [-1, 0] и стремится к [0, 0]. [nticks,1000] — этот параметр задает число точек для интерполяции графика. Чем их больше — тем более гладким будет выглядеть график и больше времени потребуется на его построение.
Графики в полярных координатах — применяется функция draw2d со следующими аргументами:
- user_preamble = «set grid polar», // построение в полярных координатах;
- nticks = n, // n — число точек;
- xrange = [dx1, dx2], // диапазон изменения x;
- yrange = [dy1, dy2], // диапазон изменения y;
- color = red, // цвет;
- line_width = k, // ширина линии, которой строится график;
- title = «общее название графика»,
- polar(функция, переменная, нижняя_граница _переменной, верхняя_граница_переменной) // функция построения графика;
Обязательными являются первый и последний аргументы функции. Первый инициирует построение графика в полярных координатах, последний (polar) — это функция, по которой строится график.
plot3d(((x — 10)/5)*((y — 10)/5),[x, 0,20],[y, 0,20]) — трехмерная (3D) графика;
Редактирование трехмерного графика осуществляется так же, как и двумерного.
Трехмерная поверхность может быть заменена градиентным переходом цветов. Для этого следует применить опцию «set view map».
Программирование (подробнее в документации)
for, while, until и т.д.
Примеры:
- for i in s do
- for k:1 thru b:3 do
- for переменная: начало step шаг thru конец do выражение
- for переменная: начало step шаг while условие do выражение
- for переменная: начало step шаг unless условие do выражение
Задание функции:
f1(x,y):=x+y;
Другое
Русское обозначение — обозначение в Maxima:
- arccos — acos
- arcsin — asin
- arctg — atan
- ch — cosh
- sh — sinh
- ctg — cot
- ln — log
- tg — tan
Символы греческого алфавита: Gamma; Theta; Psi и т.д.
Обработка данных
1)
load (descriptive); /*загрузить расширение*/
a:[1,2,3,4];
mean(a); /*=5/2 среднее*/
var(a); /*=5/4 дисперсия*/
std(a); /*=?5/2 среднеквадратичное отклонение*/
mean (средняя арифметическая);
median (медиана);
variance (дисперсия);
deviation (среднее квадратичное отклонение);
2)
a:[1.0,2.0,3.0,4.0];
for i in a do ldisp( sin(i)/i );
Вычисление производных по всем переменным, входящим в выражение:
eq: x*l/k; /*исходное выражение*/
res: 0$ for i in listofvars(eq) do res: res + (diff(eq,i) * concat(«d»,(i)))^2$
Для большей точности существует специальная функция bfloat() (big float, большой float), а также переменная ffprec — за число знаков после запятой. То есть для повышения/понижения точности нужно присвоить переменной fpprec другое числовое значение и воспользоваться функцией bfloat() вместо float(). Нужно, чтобы переменная numer равнялась false.
По умолчанию Maxima работает в системе МКС: метр-килограмм-секунда:
- 2*m;
- 2*cm;
- setunits([centigram,inch,minute]) — аргументами которой являются три базовых единицы измерения: веса, длины и времени;
- setunits([kg, m, s]);
- convert(inch,[sm]); — перевод единиц измерения;
stringout("/Users/myusername/file1maxima.mc",INPUT);
To save all your work as a «tape» that can be replayed later, all your input can be saved to a file.
batch("/Users/myusername/file1maxima.mc");
Loading the saved file: the saved file can also be loaded directly, although the exact numbering of lines will change from the original calculation.
SIMPSUM:TRUE;
sum(k, k, 1, n), simpsum;
=> \displaystyle {{n^2+n}\over{2}}
product(1/(n^2),n,1,10); Products work in much the same way.
niceindices(powerseries(%e^x, x, 0));
=> \displaystyle \sum_{i=0}^{\infty }{{{x^{i}}\over{i!}}}
taylor(%e^x, x, 0, 5);
=> \displaystyle 1+x+{{x^2}\over{2}}+{{x^3}\over{6}}+{{x^4}\over{24}}+{{x^5}\over{120 }}+\cdots
trunc(%); Since the output of taylor has special properties, we need to convert it into a polynomial.
load(«newton»);
=>/sw/share/maxima/5.9.0rc3/share/numeric/newton.mac
newton(x^7-5*x^6+4*x^4-5*x^2+x+2,1);
=>8.194213634964119B-1
tex(%)- преобразовать выражение к виду TeX;
$$\left(x+1\right)^2$$
Преобразовать TeX в PDF
1. Paste the following five lines verbatim into the text editor:
\documentclass{article}
\pagestyle{empty}
\begin{document}
\huge
\end{document}
2. Copy the tex() output line, and paste it between the \huge and \end{document} lines.
3. Save the result in text format as: myoutput.txt
4. In the terminal window, navigate to the directory where you saved myoutput.txt
5. type:
pdflatex myoutput.txt
6. Hit return — a PDF file called myoutput.pdf containing your typeset equation will now be created in this directory.
load(to_poly_solve); — дополнительные процедуры для решения систем алгебраических уравнений;
to_poly_solve([3*z1+z2+2=0,sqrt(z1)=z2],[z1,z2]);
sol:rk([rk1, rk2, gamma, w], [gamma, w, fi, tetta], [0, %pi/8, %pi/2, 0], [t, 0, Tmax with_stdout («gamma.txt», for k:1 thru points do print (sol[k][1], sol[k][2])) — пример ввода данных из файла.
А теперь рассмотрим типовой пример использования Maxima в студенческой жизни. Красиво и интересно данный процесс был показан в статье на Хабре ранее (http://habrahabr.ru/post/193272/). Я в свою очередь только поверну координатные оси в одном уравнении:
F:uxx+2*uxy+cos(x)^2*uyy-ctg(x)*(ux+uy); /*искомое уравнение*/
A:F,uxx=uxx,uxy=0,uyy=0,ux=0,uy=0$ A:A/uxx$
B:F,uxx=0,uxy=uxy,uyy=0,ux=0,uy=0$ B:B/(2*uxy)$
C:F,uxx=0,uxy=0,uyy=uyy,ux=0,uy=0$ C:C/(uyy)$
D:F,uxx=0,uxy=0,uyy=0,ux=ux,uy=0$ D:D/(ux)$
E:F,uxx=0,uxy=0,uyy=0,ux=0,uy=uy$ E:E/(uy)$
print("A = ",A)$ print("B = ",B)$ print("C = ",C)$ print("D = ",D)$
... print("E = ",E)$
delta:B^2-A*C$
print("Delta = ", delta)$
/*так как я знаю, что дельта > 0, перехожу сразу
к решению гиперболического уравнения */
A*'diff(y,x,1)^2-2*B*'diff(y,x,1)+C=0;
'diff(y,x,1)=(2*B+sqrt((2*B)^2-4*A*C))/(2*A);
ode2(%,y,x);
solve(%,%c)$
w1:rhs(%[1])$ print("w1 = ",w1)$
'diff(y,x,1)=(2*B-sqrt((2*B)^2-4*A*C))/(2*A);
ode2(%,y,x);
solve(%,%c)$
w2:rhs(%[1])$ print("w2 = ",w2)$
ux:un*diff(w2,x)+ue*diff(w1,x);
uy:un*diff(w2,y)+ue*diff(w1,y);
uxx:un*diff(diff(w2,x),x)+unn*diff(w2,x)^2+2*uen*diff(w1,x)*diff(w2,x)
... +ue*diff(diff(w1,x),x)+uee*diff(w1,x)^2;
uxy:un*diff(diff(w2,x),y)+uen*(diff(w1,x)*diff(w2,y)+diff(w1,y)*diff(w2,x))
... +unn*diff(w2,x)*diff(w2,y)+ue*diff(diff(w1,x),y)+uee*
diff(w1,x)*diff(w1,y);
uyy:un*diff(diff(w2,y),y)+unn*diff(w2,y)^2+2*uen*diff(w1,y)*diff(w2,y)
... +ue*diff(diff(w1,y),y)+uee*diff(w1,y)^2;
uy*E+ux*D+uyy*C+2*uxy*B+uxx*A;
%,ctg(x)=cos(x)/sin(x); trigrat(%);
Результат:
2*uen*cos(2*x)-2*uen