|
Персональные инструменты |
|||
|
MaximaМатериал из CustisWikiMaxima — система компьютерной алгебры, реализованная на языке 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
Например, вычислим , а затем возьмем корень 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 Если вы забудете ввести «;» — Maxima будет терпеливо (т. е. без каких-либо сообщений об ошибках) продолжать ввод ввод, пока вы ее не введете «;». Можно вместо точки с запятой завершить команду знаком доллара «$», тогда вывод этой команды будет заглушён, то есть, команда будет обработана и результат будет вычислен, но не выведен на экран. Введем какое-нибудь выражение с переменной: (%i2) (x + 2)*(x - 3); Ответ Maxima содержит то же выражение, в неупрощенной форме: (%o2) (x - 3) (x + 2) 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 будет выглядеть так: . Пользуясь этой возможностью, далее в этом введении, все математические формулы, получаемые от 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 Разумеется, в TeX-форматировании интеграл будет выглядеть красивее: В таком случае, можно помочь системе, выполнив замену переменных: 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; →
Разложение на простые дроби: шаг за шагомОтветы 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(%)); → Напомним, мы использовали следующие функции:
Вычисление пределов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); → Версия 5.9.3. содержит баг 1517061 Далее, можно просуммировать, как мы уже делали выше: ev (sc, simpsum=true); → Внешние ссылки
Любые правки этой статьи будут перезаписаны при следующем сеансе репликации. Если у вас есть серьезное замечание по тексту статьи, запишите его в раздел «discussion». Репликация: База Знаний «Заказных Информ Систем» → «Maxima» |
||