Maxima — различия между версиями
м (1 версия) |
(нет различий)
|
Текущая версия на 16:47, 23 октября 2008
Maxima — система компьютерной алгебры, реализованная на языке Lisp.
Maxima имеет широчайший набор средств для проведения аналитических вычислений, численных вычислений и построения графиков. По набору возможностей система близка к таким коммерческим системам как Maple и Mathematica. В то же время она обладает высочайшей степенью переносимости. Это единственная из существующих систем аналитических вычислений, которая может работать на всех современных операционных системах, на компьютерах, начиная от самых мощных, заканчивая наладонниками.
Содержание
История
Maxima произошла от системы «Macsyma», разрабатывавшейся в MIT (Massachusetts Institute of Technology) с 1968 по 1982.
Вариант продукта (известный как DOE Macsyma) сопровождался профессором Уильямом Шелтером в Техасском Университете с 1982 до своей смерти в 2001.
В 1998, Шелтер получил от Департамента энергии разрешение опубликовать исходный код DOE Macsyma под лицензией GPL, и в 2000 он создал проект «Maxima» на SourceForge для поддержания и развития «DOE Macsyma», переименованного в Maxima.
Введение
Обзор
Maxima может использоваться как мощный калькулятор:
(%i13) 144*17 - 9; (%o13) 2439
Maxima поддерживает точные вычисления с большими числами,
размер которых ограничен только ресурсами вашего компьютера.
Например, вычислим , а затем возьмем корень 25-степени из результата:
(%i14) 144^25; (%o14) 910043815000214977332758527534256632492715260325658624 (%i15) %^(1/25); (%o15) 144
Знак «%» ссылается на специльную переменную, хранящую результат последней операции. Знак «^» — оператор возведения в степень.
Однако основное назначение компьютерной алгебры — не численные вычисления, а скорее, символьные операции. Поиграем с полиномом :
expand((x + 2*y)^4); → factor(%); →
Вычисление производных:
diff(sin(x)*cos(x), x); → trigsimp(%); → diff(%, x); → diff( sin(x)*cos(x), x, 2); →
и первообразных (неопределенных интегралов):
integrate((x + 1)/(x^3 - 8), x); →
Maxima может преобразовывать тригонометрические выражения в канонические конечные тригонометрические ряды (Fourier sums):
trigreduce (sin(x)^5); →
Первые шаги
Maxima ориентирована на минималистический интерфейс командной строки — т. е. сеанс работы состоит из последовательных команд пользователя и полученных на них ответов.
Команда — это некое выражение, возможно многострочное, оканчивающееся точкой с запятой «;». Например на команду:
(%i1) 14*(7 + 3);
будет получен ответ:
(%o1) 140
Файл:Note.svgЕсли вы забудете ввести «;» — Maxima будет терпеливо (т. е. без каких-либо сообщений об ошибках) продолжать ввод ввод, пока вы ее не введете «;».
/bin/bash: inkscape: command not found /bin/bash: inkscape: command not found
Введем какое-нибудь выражение с переменной:
(%i2) (x + 2)*(x - 3);
Ответ Maxima содержит то же выражение, в неупрощенной форме:
(%o2) (x - 3) (x + 2)
Файл:Note.svg Maxima выдает выражение-результаты, используя минималистические средства — текстовую отрисовку формул. Так в ответе «(%o2)» мы видим, что за счет исключения «*» из ответа, выражение выглядит «математическим», а не программистким.
Теперь раскроем скобки:
(%i3) expand(%); 2 (%o3) x - x - 6
Т.е. человек вполне способен прочесть эту ASCII-формулу, однако, есть возможность получить эту формулу (c помощью функции «tex») в формате TeX:
(%i38) tex( expand( (x + 2)*(x - 3) ) ); $x^2-x-6$ (%o38) false
Что, если отрисовать через TeX будет выглядеть так: .
Файл:Note.svg Пользуясь этой возможностью, далее в этом введении, все математические формулы, получаемые от Maxima мы будем отрисовывать через TeX, что будет гораздо удобней для чтения, чем ASCII-графика, особенно в случае «многоэтажных» формул.
Итак, возведение в степень:
x^3^4; →
Обратите внимание на приоритет операций: x^3^4 есть
Дифференцирование и интегрирование
Возьмем неопределенный интеграл для :
integrate(x/(x^3 + 1), x); →
Продифференцируем результат для проверки:
diff(%, x); →
И чтобы, не пугаться, упростим сумму рациональных выражений:
ratsimp(%); →
Повторим тоже самое для :
integrate(exp(a*x)*sin(x)*cos(x), x); → diff(%, x); → ratsimp(%); → trigexpand(%); →
Если Maxima не смогла взять интеграл — она возвращает интеграл в «исходной форме»:
(%i4) integrate(1/((x-3)^4+1/2), x); / [ 1 (%o4) I ------------ dx ] 4 1 / (x — 3) + - 2
/bin/bash: inkscape: command not found /bin/bash: inkscape: command not found
В таком случае, можно помочь системе, выполнив замену переменных:
changevar (%, x - 3 - y ,y ,x); →
а затем проинтегрировав:
ev (%, integrate)
выполним обратную подстановку
sfx: %, y=x-3;
Т.к. подынтегральное выражение — всюду определенная положительная функция, мы можем вычислить определенный интеграл , используя вычисленную первообразную «sfx»:
ratsimp(subst (1, x, sfx) - subst(0, x, sfx));
или переходя к значениям в плавающей арифметике:
float(ratsimp(subst (1, x, sfx) - subst(0, x, sfx))); → 0.028806333852738
Для проверки выполним численное интегрирование методом Ромберга:
romberg(1/((x-3)^4+1/2), x,0, 1); → 0.028806333924554
Результаты аналитического и численного интегрирования совпадают с точностью 1e-10.
Проинтегрируем .
integrate(((6*x^5 + 7*x^4 - 36*x^3 + 18*x - 21)*(x^4 + 1)^(2/3) + (2*x^6 - 20*x^4 - 40*x^3 + 18*x^2 + 12)*(x^4 + 1)^(1/3)) /(3*x^8 +6*x^4 + 3), x);
Осталось «сократить» экспоненты с логарифмами, перейдя к каноническому радикалу:
radcan(%);
Решение полиномов
Нахождение нулей у полиномов от одной переменной — задача известная со школы. Поиграем с ней для демонстрации некоторых возможностей Maxima. Определим переменную poly:
poly: x^2 - x - 12; →
Вычислим нули, используя функцию «solve»:
solutions: solve (poly=0, x); → [ x=-3, x=4 ]
Мы получили ответ в виде двух равенств (с левыми и правыми частями) — если их преобразовать в множители, то мы должны получить исходный полином, в виде их произведения.
Воспользуемся механизмом лямбда-функций (по сути, безымянных функций). Лямбда функция
lambda ([eq], lhs(eq) - rhs(eq))
очевидным образом преобразует выражение-равенство, в множитель, равный нулю в точке равенства. Итак, применим функцию «map», применяющую нашу лямбда-функцию для всех элементов нашего списка уравнений:
map( lambda( [eq], lhs(eq) - rhs(eq)), solutions); → [x+3,x-4]
Перемножим этот список:
apply("*", %); → (x-4)(x+3)
И, раскрыв скобки, получаем исходный полином:
expand(%); →
Тригонометрические преобразования
Чтобы преобразовать произведения синусов-косинусов, в триногометрический ряд Фурье, используется функция «trigreduce»:
trigreduce(sin(x)^3*cos(x)); →
Теперь избавимся от произведений в аргументах тригонометрических функций:
trigexpand(%); →
И наконец, упрощаем выражение, используя функцию «trigsimp», знающую тождество :
trigsimp(%); →
Упрощение тригонометрических выражений не всегда получается просто и быстро, как в приведенном примере, и в почтовых рассылках часто раздаются вопросы, «как мне упростить XXX?» или «почему Maxima не упрощает YYY?».
Рассмотрим пример:
result:integrate(9/cos(7*x)^2, x); →
А пользуясь любым матсправочником с таблицей основных первообразных (например, справочником Бронштейна-Семендяева), легко получить более красивый результат: .
Попробуем упростить «влоб»:
simp1: trigsimp(result); →
Но применять дальше «trigexpand», для раскрытия sin(14*x) и cos(14*x) через sin(x) и cos(x) бесполезно — выражение сильно усложнится. Надо бы выразить sin(14*x) и cos(14*x) через sin(7*x) и cos(7*x), а для этого надо сделать подстановку, заменив 14*x на 2*y.
simp2: simp1, 14*x=2*y; →
И далее:
trigexpand(simp2); → trigsimp(%); →
и наконец:
trigreduce(%); →
возвращаемся к исходным переменным:
%, y = 7*x; →
Итак, мы показали на примере этой задачки, как важно использовать подстановки переменных при упрощении через «trigexpand». А вообще, это выражение можно было упростить одним действием:
trigrat(result); → trigreduce(%); →
Проверим результат интегрирования:
deriv: diff(result, x); trigrat(deriv); →
Выглядит просто, но чтобы сравнить с исходным выражением, надо выразить всю «тригонометрию» через 7x.
%, 14*x = 2*y; → trigexpand(%); → trigsimp(%); → %, y = 7*x; →
Итак, напомним еще раз назначение рассмотренных функций:
- trigreduce
- преобразует тригонометрическое выражение как сумма слагаемых, каждое из которых содержит один синус или косинус.
- trigexpand
- «раскрывает» аргументы тригонометрических функций, согласно правилам тригонометрических функций от суммы углов.
- trigsimp
- упрощает тригонометрическое выражение, используя тождество .
- trigrat
- мощная функция — упрощение рационального тригонометрического выражения.
Разложение на простые дроби: шаг за шагом
Ответы Maxima всегда показывают готовый результат (если, конечно, системе удалось его получить), но не путь его вычисления.
Например, разложение на простые дроби выполняется функцией «partfrac»:
partfrac ( 1/(x^2*(x^2 + 1)), x); →
Обычно этого достаточно, ибо полученный результат вполне можно проверить. Однако, иногда требуется получить последовательность вычислений (например, если это часть домашней работы, и проверяющему недостаточно предьявить ответ).
Итак, попробуем вычислить разложение в «полуавтоматическом» (или «полуручном») режиме.
В данном случае, разложение на простые дроби — это сумма следующих элементарных дробей:
p1: a/x; → p2: b/x^2; → p3: (c*x + d)/(x^2 + 1); →
т. е.
p1 + p2 + p3; →
Приводим к общему знаменателю, и поименуем числитель этой дроби, как «n»:
ratsimp(p1 + p2 + p3); → n: num(%); →
Теперь осталось решить уравнение, «приравняв» числитель исходной дроби и числитель «n»:
solve ([coeff (n, x, 3) = 0, coeff (n, x, 2) = 0, coeff (n, x, 1) = 0, → [[a=0,b=1,c=0,d=-1]] coeff (n, x, 0) = 1], [a, b, c, d]);
Наконец, подставляем полученные коэффициенты:
at(p1 + p2 + p3, first(%)); →
Напомним, мы использовали следующие функции:
- num
- возвращает числитель дроби.
- coeff
- возвращает коэффициент при переменной в заданной степени.
- solve
- решает систему линейных уравнений.
Вычисление пределов
Maxima может вычислять пределы для широкого спектра как рациональных, так и трансцедентных функций.
Для рациональных функций, часто интересно посмотреть поведение функции на бесконечности:
limit ((x^2 - 1)/(x^2 + 1), x, inf); →
Можно раскрыть и предел типа «0/0»:
limit ((x^2 + x - 6)/(x^4 + x^3 - 19*x^2 + 11*x + 30), x, 2); →
Maxima умеет вычислять пределы «справа» и «слева», и честно сообщает, когда предел в заданной точке не определен:
limit (tan(x), x, %pi/2, plus); → minf limit (tan(x), x, %pi/2, minus); → inf limit (tan(x), x, %pi/2); → und
Вычисление рядов — конечных и бесконечных
Конечные суммы считаются сразу:
sum(i, i, 1, 100); → 5050
Но бесконечные ряды, по умолчанию не суммируются, выражение остается в исходном символьном виде:
sum1:sum(1/x^2, x, 1, inf); → sum2:sum(1/x^2, x, 1, inf); →
Чтобы выполнить суммирование, нужно указать опцию «simpsum=true»:
sum(1/x^2, x, 1, inf), simpsum=true; →
Впрочем, над «непросуммированными суммами» можно выполнять операции, только операторы суммирования не будут сокращаться:
sum1+sum2; →
Для сокращения сумм, нужно использовать функцию «sumcontract»:
sc:sumcontract(sum1+sum2); →
Файл:Caution.svg Версия 5.9.3. содержит баг 1517061
Далее, можно просуммировать, как мы уже делали выше:
ev (sc, simpsum=true); →
Внешние ссылки
- Домашняя страница Maxima
- Maxima в Википедии.
- Вадим Житников-Компьютеры, математика и свобода
- Maxima – максимум свободы символьных вычислений
- Maxima: максимум удобства и функциональности
- WxMaxima — оконный интерфейс к Maxima.
- GNU TeXmacs - набор маттекстов в TeX, с плагинами доступа к различным CAS-системам, типа Axiom, Reduce, и в частности Maxima.