Maxima — Tips&Tricks, или собираем по крохам инфо, как на ней работать

в 17:31, , рубрики: компьютерная алгебра, математика

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

Я думаю, всем из нас известна данная система компьютерной алгебры. Она не является конкурентом Wolfram Mathematica, но она обладает именно тем функционалом, который я требую от математического софта. Если говорить проще и доступнее — считать можно на всём, от палочек до суперкомпьютеров, и далеко не всегда задачи инженерной практики целиком переносятся с бумаги в программный код. Одним из примеров, который я честно говоря, еле-еле застал, является сегодня забытая поделка нашего конверсионного производства — цельнометаллический бытовой вакуумный гражданский термос, который выпускался ранее ещё в СССР на Урале. Чтобы наладить его производство институт, в котором я учусь, де-факто вручную на счётных машинках высчитал все необходимые параметры рабочего оборудования. Поэтому лицензия на Mathematica — не показатель и не ценз пригодности к практике. Считать, повторюсь, можно на всём.

От слов к делу. Ниже разбиты на категории те моменты в документации Maxima, которые желательно знать для начинающего пользователя данной СКА.

Общий функционал

** или ^ — возведение в степень;
% — последняя ячейка вывода;
_ — последняя ячейка ввода;
%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+1right)^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 в студенческой жизни. Красиво и интересно данный процесс был показан в статье на Хабре ранее. Я в свою очередь только поверну координатные оси в одном уравнении:

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

Автор: Kazancev

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js