[327e91]: ru / maxima-tarnavsky-3.xml  Maximize  Restore  History

Download this file

182 lines (96 with data), 40.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../main.xsl"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="maxima-tarnavsky-3" xml:lang="ru">
<head>
<title>Тихон Тарнавский. Maxima&#x00a0;— укротитель выражений</title>
<link rel="schema.DC" href="http://purl.org/dc/elements/1.1/"/>
<link rel="schema.DCTERMS" href="http://purl.org/dc/terms/"/>
<meta name="DC.identifier" scheme="DCTERMS.URI" content="http://maxima.sourceforge.net/ru/maxima-tarnavsky-3.html"/>
</head>
<body>
<p>Впервые было опубликовано в «<a href="http://www.linuxformat.ru/">Linux Format</a>» <a href="http://www.linuxformat.ru/download/83.pdf">№9 (83), сентябрь 2006&#x00a0;г</a>.</p>
<p>В этот раз я расскажу о штатных возможностях Maxima по упрощению и прочим преобразованиям выражений. В частности, речь пойдет об автоматическом раскрытии скобок и вынесении за скобки; об упрощении как арифметических действий над некоторыми элементами, так и выражений с участием степенных, показательных и логарифмических функций; а также об обработке тригонометрических выражений. Все эти функции призваны облегчать читаемость математических формул и повышать простоту их восприятия, а посему стоит уделить этому уроку достаточно внимания: при верном использовании данные манипуляции позволят сэкономить в процессе работы значительное количество времени.</p>
<h3>Выражаясь рационально…</h3>
<p>Существенная часть интересующих нас сегодня функций предназначена для преобразования рациональных выражений. Напомню, рациональным называется выражение, состоящее только из арифметических операторов и возведения в натуральную степень; естественно, элементы такого выражения могут содержать и неарифметические и нестепенные функции&#x00a0;— тогда такие элементы с точки зрения рационального выражения считаются атомарными, т.е. неделимыми и непреобразуемыми.</p>
<p>Функции, работающие с рациональными выражениями, описаны в разделе документации «<em>Polynomials</em>»; потому как рациональные функции с математической точки зрения рассматриваются как расширение многочленов (полиномов)&#x00a0;— примерно так же, как рациональные числа считаются расширением целых (многочлены, кстати, тоже иногда называют целыми функциями; хотя общий математический смысл этого термина несколько шире).</p>
<p>Имена всех функций Maxima по обработке рациональных выражений содержат буквосочетание <kbd>rat</kbd>, но не от слова <em>крыса</em>, а от слова <em>rational</em>. И начнем мы знакомство с ними с функции, которая так и называется: <kbd>rat(выражение)</kbd>. Эта функция преобразовывает рациональное выражение к так называемой <em>канонической форме</em> (<em>Canonical Rational Expression</em>, <em>CRE</em>). То есть раскрывает все скобки, затем приводит все к общему знаменателю, суммирует и сокращает; кроме того, приводит все числа в конечной десятичной записи к рациональным.</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-01.png" alt="" /></p>
<p>Тут надо заметить, что атомарные элементы, т.е. символы и числа, в канонической форме рационального выражения в Maxima имеют другое внутреннее представление. При работе в интерфейсах Maxima и xMaxima об этом напоминает приписка <kbd>/R/</kbd> после имени ячейки вывода (в wxMaxima и TeXmacs такая приписка отсутствует). При этом внешне, на видимом пользователю уровне, каноническая форма ничем, кроме этого обозначения, от общей не отличается. Но один достаточно интересный момент здесь есть: если каноническая форма рационального выражения используется в других рациональных выражениях, то последние также автоматически приводятся к канонической форме:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-02.png" alt="" /></p>
<p>Это может быть достаточно удобно, если вам нужно пошагово проделать большое количество рациональных преобразований: вы можете, один раз вызвав <kbd>rat()</kbd>, ссылаться на предыдущие ячейки и благодаря этому далее автоматически видеть на каждом шаге итоговое выражение в канонической, а значит, достаточно компактной и удобной к восприятию, форме. Если на каком-то этапе такое поведение станет вам мешать, вы можете вернуть выражение из канонической к общей форме с помощью функции <kbd>ratdisrep(выражение)</kbd>. Кроме того, каноническая форма автоматически «отменяется» и в случае любых преобразований, не являющихся рациональными:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-03.png" alt="" /></p>
<p>Здесь, хотя <kbd>%o2</kbd> было выражением в канонической форме, <kbd>%o3</kbd>&#x00a0;— уже выражение общего вида, так как оно не является рациональным.</p>
<p>Скажем пару слов о приведении конечной десятичной записи чисел к рациональной. Конечная десятичная запись считается по определению приблизительной, что и понятно, т.к. при вычислениях самой Maxima такая запись может возникнуть исключительно при применении приближенных методов либо при ручном указании о переводе числа в десятичную запись из математической, в результате чего результат тоже, вероятнее всего, окажется приблизительным. Эта приблизительность учитывается и при переводе в рациональные числа, а ее уровень, то есть мера, на которую рациональное число при переводе может отклониться от конечной десятичной записи, регулируется переменной <kbd>ratepsilon</kbd>, равной по умолчанию <kbd>2.0e-8</kbd>, т.е. <kbd>0.00000002</kbd>. Если такое положение вещей вас не устраивает, вы можете убедить Maxima оставлять десятичную запись чисел как есть, установив в <kbd>true</kbd> значение флага <kbd>keepfloat</kbd> (по умолчанию он равен <kbd>false</kbd>).</p>
<p>Следующая функция раскрывает скобки в рациональном выражении и называется <kbd>ratexpand()</kbd> (одно из значений слова <em>expand</em> и есть «раскрыть скобки»). Здесь также действует опция <kbd>keepfloat</kbd>. Кроме нее, есть еще одна опция&#x00a0;<kbd>ratdenomdivide</kbd>; по умолчанию она установлена в <kbd>true</kbd>, что приводит к тому, что каждая дробь, в которой числитель является суммой, распадается на сумму дробей с одинаковым знаменателем. Если же сбросить эту опцию в <kbd>false</kbd>, тогда все дроби с одинаковым знаменателем будут, напротив, объединены в одну дробь с числителем в виде суммы числителей изначальных дробей. То есть внешне результат будет в этом случае выглядеть почти так же, как и у функции <kbd>rat()</kbd>; к тому же единственная видимая пользователю разница проявляется только в рациональных выражениях от нескольких переменных (или различных иррациональных выражений). Заключается эта разница в том, что после <kbd>ratexpand()</kbd> и в числителе, и в знаменателе дроби все скобки будут раскрыты, в случае же <kbd>rat()</kbd> слагаемые, где присутствуют, скажем, две переменных, будут сгруппированы, и одна из них будет вынесена за скобки (в документации такая форма записи называется «рекурсивной» (<em>recursive</em>):</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-04.png"><img src="i/tarnavsky/3/maxima3-04-thumb.png" alt="" /></a></p>
<p>Кроме того, разница, конечно, заключается и во внутреннем представлении: с точки зрения программы, после ratexpand() выражение будет по-прежнему общего вида. Соответственно и все результаты дальнейших рациональных действий с выражением не будут автоматически «канонизироваться». Я специально обращаю ваше внимание на схожесть между результатами этих двух различных функций, поскольку в документации эта схожесть никак не обозначена: в описании обеих функций и примерах к ним нет вообще никаких ссылок друг на друга.</p>
<p>Помимо флага <kbd>ratdenomdivide</kbd>, есть также функция, собирающая воедино дроби с одинаковыми знаменателями; зовут ее <kbd>combine()</kbd>:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-05.png" alt="" /></p>
<p>В дополнение к функции <kbd>ratexpand()</kbd> есть также флаг <kbd>ratexpand</kbd>, который по умолчанию равен <kbd>false</kbd>, а будучи установлен в <kbd>true</kbd>, приводит к тому, что все рациональные выражения в канонической форме отображаются и преобразовываются к общему виду сразу же с раскрытыми скобками:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-06.png"><img src="i/tarnavsky/3/maxima3-06-thumb.png" alt="" /></a></p>
<p>Обратите внимание, что при применении этого флага выражение сохраняет каноническую форму.</p>
<p>Действует в этом случае и флаг <kbd>ratdenomdivide</kbd> (напомню, что в строке <kbd>%i1</kbd> этот флаг был установлен локально, используя сокращенную запись функции <kbd>ev()</kbd>):</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-07.png" alt="" /></p>
<p>Иными словами, флаг ratexpand по своему действию аналогичен одноименной функции, но действует он на все без исключения канонические рациональные выражения и при этом оставляет их в канонической внутренней записи и изменяет только внешнее отображение этой записи, сохраняя при этом и дальнейшую автоматическую «канонизацию».</p>
<h3>…и не только рационально.</h3>
<p>Помимо <kbd>ratexpand()</kbd> есть также и функция «просто» <kbd>expand()</kbd>. Различий между ними несколько, наиболее принципиальные таковы. Вопервых, <kbd>ratexpand()</kbd> раскрывает только рациональное выражение «верхнего уровня», все же подвыражения, не являющиеся рациональными, обрабатываются как атомарные, то есть внутрь них она не залезает; <kbd>expand()</kbd> же раскрывает скобки на всех уровнях вложенности:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-08.png" alt="" /></p>
<p>Во-вторых, <kbd>ratexpand()</kbd> приводит дроби-слагаемые к общему знаменателю, а <kbd>expand()</kbd> этого не делает; в-третьих, на функцию expand не действует переключатель <kbd>ratdenomdivide</kbd>:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-09.png"><img src="i/tarnavsky/3/maxima3-09-thumb.png" alt="" /></a></p>
<p>И в-четвертых, <kbd>expand()</kbd> не преобразовывает к рациональным числам конечную десятичную запись&#x00a0;— опять-таки, вне зависимости от флага <kbd>keepfloat</kbd>.</p>
<p>Функция <kbd>expand()</kbd>, в отличие от своего рационального сородича, имеет несколько вариаций&#x00a0;— в виде отдельных функций с похожими названиями, которые раскрывают скобки несколько по-разному. Первую мы уже рассмотрели. Вторая называется <kbd>expandwrt(выражение,&#x00a0;x,&#x00a0;y,&#x00a0;…,&#x00a0;v)</kbd>, где <em>wrt</em> расшифровывается как «with respect to…», то есть «относительно…». Она раскрывает скобки не везде, а только относительно тех символов, которые заданы в списке аргументов после выражения. Другими словами, только там, где из скобок можно вынести хотя бы один из перечисленных символов:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-10.png"><img src="i/tarnavsky/3/maxima3-10-thumb.png" alt="" /></a></p>
<p>(На предупреждение, возникающее при первом вызове функций <kbd>expandwrt*()</kbd>, можете не обращать внимания&#x00a0;— на функционале, о котором идет речь, оно никоим образом не отражается.)</p>
<p>Если в выражении встречаются дроби, то по умолчанию эта функция раскрывает скобки только в их числителях, оставляя знаменатели в покое. Изменить это поведение можно переключателем <kbd>expandwrt_denom</kbd>, установив его в <kbd>true</kbd> (по умолчанию он равен <kbd>false</kbd>):</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-11.png"><img src="i/tarnavsky/3/maxima3-11-thumb.png" alt="" /></a></p>
<p>И, наконец, последняя функция из этого семейства&#x00a0;<kbd>expandwrt_factored(выражение,&#x00a0;x,&#x00a0;y,&#x00a0;…,&#x00a0;v)</kbd>&#x00a0;— раскрывает скобки лишь в тех слагаемых, где упомянутые символы встречаются не в одном, а в каждом из сомножителей:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-12.png"><img src="i/tarnavsky/3/maxima3-12-thumb.png" alt="" /></a></p>
<p>Раскрытием возведения в целую степень можно управлять как в контексте функции <kbd>expand()</kbd>, так и отдельно. В первом случае применяются переменные maxposex и maxnegex, определяющие соответственно максимальные положительный и отрицательный показатель степени, которые будут раскрываться этой функцией. По умолчанию оба параметра равны <kbd>1000</kbd>. Переназначить их можно не только глобально, но и в контексте одного конкретного вызова функции <kbd>expand()</kbd>&#x00a0;— в таком случае это делается с помощью дополнительных аргументов, задаваемых после выражения:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-13.png"><img src="i/tarnavsky/3/maxima3-13-thumb.png" alt="" /></a></p>
<p>В противовес <kbd>maxposex</kbd> и <kbd>maxnegex</kbd> можно задать максимальные положительную и отрицательную степени, которые будут раскрываться автоматически, без вызова функций группы <kbd>expand</kbd>. За это отвечают переменные <kbd>expop</kbd> и <kbd>expon</kbd>, и по умолчанию они равны нулю, то есть автоматически степени не раскрываются вообще.</p>
<p>Кроме самостоятельной функции <kbd>expand()</kbd>, существуют также флаги <kbd>expand</kbd> и <kbd>expand(p,&#x00a0;n)</kbd> у функции <kbd>ev()</kbd>. Запись выражение, <kbd>expand</kbd> равносильна <kbd>expand(ev(выражение))</kbd>, а выражение <kbd>expand(p,&#x00a0;n)</kbd>&#x00a0;<kbd>expand(ev(выражение,&#x00a0;p,&#x00a0;n))</kbd>.</p>
<p>Возможности управлять раскрытием скобок на этом не заканчиваются. Еще одна функция&#x00a0;<kbd>distrib()</kbd>&#x00a0;— представляет как бы облегченный вариант <kbd>expand()</kbd>. Она действует аналогично <kbd>expand()</kbd>, но только на один уровень в глубину:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-14.png"><img src="i/tarnavsky/3/maxima3-14-thumb.png" alt="" /></a></p>
<p>В противоположность функциям <kbd>*expand*()</kbd>, раскрывающим скобки, можно также и разложить выражение на множители, то есть максимально повыносить все за скобки. Делается это с помощью функции <kbd>factor()</kbd>:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-15.png"><img src="i/tarnavsky/3/maxima3-15-thumb.png" alt="" /></a></p>
<p>Если функции <kbd>factor()</kbd> передать целое число, она разложит его на простые множители; если же передать рациональное число&#x00a0;— на множители будут разложены его числитель и знаменатель:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-16.png"><img src="i/tarnavsky/3/maxima3-16-thumb.png" alt="" /></a></p>
<p>Если многочлен не может быть представлен в виде произведения нескольких сомножителей, его можно попытаться преобразовать в сумму таких произведений с помощью функции <kbd>factorsum()</kbd>:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-17.png"><img src="i/tarnavsky/3/maxima3-17-thumb.png" alt="" /></a></p>
<p>Функция <kbd>factorsum()</kbd> умеет раскладывать на множители только независимые слагаемые, то есть такие, которые не содержат одинаковых переменных. Если мы раскроем скобки в выражении, содержащем в двух разных местах один и тот же символ, то так как коэффициенты при этом символе после раскрытия сгруппируются, <kbd>factorsum()</kbd> не сможет понять, каким именно образом разгруппировать их обратно:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-18.png" alt="" /></p>
<p>Нужно заметить, что функции <kbd>factor()</kbd> и <kbd>factorsum()</kbd>, хотя и не имеют в имени приставки <kbd>rat</kbd>, все же ведут себя в смысле разбора передаваемых им выражений не как <kbd>expand()</kbd> и сопутствующие, а как <kbd>ratexpend()</kbd>; то есть на любой не-рациональной функции останавливаются и внутрь не идут:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-19.png" alt="" /></p>
<p>Впрочем, об этом можно догадаться из документации, так как функции <kbd>factor*</kbd> описаны не в разделе «Simplification», куда относятся <kbd>expand*</kbd>, а, так же, как и <kbd>rat*</kbd>, в разделе «Polynomials».</p>
<p>Выносить за скобки, а также раскрывать эти скобки можно не только специальной функцией, но и дополнительным флагом ко все той же канонической форме рациональных выражений. Флаг этот зовут <kbd>ratfac</kbd>, и по умолчанию он равен <kbd>false</kbd>, то есть вынесение за скобки не происходит. Если же его установить в true, то в каждом рациональном выражении, приведенном к канонической форме, все будет максимально вынесено за скобки, но без вызова функции <kbd>factor()</kbd>; например, в примере ниже не произошло обратного свертывания <kbd>(x+1)2</kbd>, хотя, будучи применен к первоначальному выражению, флаг <kbd>ratfa</kbd>c сохранил и этот множитель нераскрытым (также можете сравнить этот пример с аналогичным примером к функциям <kbd>ratexpand()</kbd> и <kbd>rat()</kbd>):</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-20.png" alt="" /></p>
<h3>Проще простого</h3>
<p>Итак, о преобразованиях выражений мы уже поговорили достаточно&#x00a0;— теперь перейдем к их упрощению. Об элементарных упрощениях мы уже говорили в предыдущий раз: они могут производиться автоматически, на что влияет установленный флаг <kbd>simp</kbd>; и по умолчанию именно так и происходит.</p>
<p>Здесь тоже все начинается с рациональных выражений, которыми занимается функция <kbd>ratsimp(выражение)</kbd>. Она упрощает выражение за счет рациональных преобразований, но, в отличие от остальных функций по обработке рациональных выражений, работает в том числе и «вглубь», то есть иррациональные части выражения не рассматриваются как атомарные, а упрощаются, в том числе, и все рациональные элементы внутри них:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-21.png" alt="" /></p>
<p>На <kbd>ratsimp()</kbd> действуют те же флаги, что и на <kbd>rat()</kbd>: и <kbd>ratexpand</kbd>, и <kbd>keepfloat</kbd>, и <kbd>ratfac</kbd>. Но отличается она от <kbd>rat()</kbd> или <kbd>ratexpand()</kbd> не только умением работать «в глубину», но и некоторыми дополнительными рациональными преобразованиями, которые не поддерживаются этими двумя функциями:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-23.png" alt="" /></p>
<p>Кроме функции <kbd>ratsimp()</kbd>, есть еще и дополнительный переключатель&#x00a0;<kbd>ratsimpexpons</kbd>. По умолчанию он установлен в <kbd>false</kbd>; если же назначить ему значение <kbd>true</kbd>&#x00a0;— это приведет к автоматическому упрощению показателей степени:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-24.png" alt="" /></p>
<p>Функция <kbd>ratsimp()</kbd>&#x00a0;— это уже достаточно мощный, и в то же время весьма быстрый, механизм упрощения; но, конечно, не достаточный: ведь те действия, которые можно упростить в разнообразных математических выражениях, не ограничиваются рациональными. Поэтому все же основной плюс этой функции&#x00a0;— это скорость. А для более серьезных упрощений существует расширенный вариант&#x00a0;<kbd>fullratsimp(выражение)</kbd>. Эта функция последовательно применяет к переданному выражению функцию <kbd>ratsimp()</kbd>, а также некоторые нерациональные преобразования&#x00a0;— и повторяет эти действия в цикле до тех пор, пока выражение не перестанет в процессе них изменяться. За счет этого функция работает несколько медленнее, чем <kbd>ratsimp()</kbd>, зато дает более надежный результат&#x00a0;— к некоторым выражениям, которые она может упростить с ходу, <kbd>ratsimp()</kbd> пришлось бы применять несколько раз, а иногда та и вообще не справилась бы с задачей.</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-25.png" alt="" /></p>
<p>И третья основная функция упрощения выражений&#x00a0;— уже никак с предыдущими двумя не соотносящаяся&#x00a0;<kbd>radcan(выражение)</kbd>. Если <kbd>ratsimp()</kbd> и <kbd>fullratsimp()</kbd> ориентированы на упрощение рациональных действий, то <kbd>radcan()</kbd> занимается упрощением логарифмических, экспоненциальных функций и степенных с нецелыми рациональными показателями, то есть корней (радикалов). Например, выражение из второго примера в этом разделе <kbd>radcan()</kbd> сможет упростить сильнее, чем <kbd>ratsimp()/fullratsimp()</kbd>:</p>
<p class="labeled-image"><img src="i/tarnavsky/3/maxima3-26.png" alt="" /></p>
<p>В некоторых случаях наилучшего результата можно добиться, комбинируя <kbd>radcan()</kbd> с <kbd>ratsimp()</kbd> или <kbd>fullratsimp()</kbd>.</p>
<p>С функцией <kbd>radcan()</kbd> смежны по действию еще два управляющих ключа. Один из них называется <kbd>%e_to_numlog</kbd>. Влияет он не на саму функцию, а на автоматическое упрощение. Если выставить его в <kbd>true</kbd>, то выражения вида <kbd>e(r*log(выражение))</kbd>, где <kbd>r</kbd>&#x00a0;— рациональное число, будут автоматически раскрываться в выражение <kbd>r</kbd>. Функция <kbd>radcan()</kbd> делает такие преобразования независимо от значения ключа. Второй ключ&#x00a0;<kbd>radexpand</kbd> (от <em>radical</em>, не путать с <kbd>ratexpand</kbd>)&#x00a0;— влияет на упрощение квадратного корня из четной степени какого-либо выражения. Он, в отличие от большинства переключателей, имеет не два, а три значения: при значении <kbd>all</kbd>, <kbd>sqrt(x2)</kbd> будет раскрываться в <kbd>x</kbd>&#x00a0;— как для действительных, так и для комплексных чисел; при значении <kbd>true</kbd> (по умолчанию), <kbd>sqrt(x2)</kbd> для действительных чисел превращается в <kbd>|x|</kbd>, а для комплексных не преобразуется; а при значении <kbd>false</kbd>, <kbd>sqrt(x2)</kbd> не будет упрощаться вообще.</p>
<p>Следующие две функции и один флаг относятся к упрощению факториалов. Функция <kbd>factcomb(выражение)</kbd> проводит упрощения вида <kbd>n!*(n+1)&#x00a0;=&#x00a0;(n+1)!</kbd> и тому подобные. Функция <kbd>minfactorial</kbd>, напротив, сокращает факториалы, то есть действует по принципу <kbd>n!/(n–1)!&#x00a0;=&#x00a0;n</kbd>. И флаг <kbd>sumsplitfact</kbd>, который изначально установлен в <kbd>true</kbd>, находясь в состоянии <kbd>false</kbd>, приводит к тому, что после того, как отработает <kbd>factcomb</kbd>, <kbd>minfactorial</kbd> вызывается автоматически.</p>
<h3>Вот под таким углом…</h3>
<p>И напоследок поговорим о функциях для преобразования тригонометрических формул. Здесь так же, как и у рациональных функций, присутствует общая для всех приставка&#x00a0;<kbd>trig</kbd>; расшифровывать ее, думаю, особой нужды нет. Начнем по традиции с функции <kbd>trigexpand(выражение)</kbd>. Она, как нетрудно догадаться, раскрывает скобки в тригонометрических выражениях:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-27.png"><img src="i/tarnavsky/3/maxima3-27-thumb.png" alt="" /></a></p>
<p>Здесь, как обычно, есть несколько управляющих флагов, первый из которых опять же является тезкой самой функции. Он приводит к повторному раскрытию всех синусов-косинусов, то есть фактически равнозначен повторному вызову самой функции:</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-28.png"><img src="i/tarnavsky/3/maxima3-28-thumb.png" alt="" /></a></p>
<p>Второй флаг&#x00a0;<kbd>halfangles</kbd>&#x00a0;— управляет раскрытием формул половинных углов. Оба эти флага по умолчанию сброшены. А следующие два флага&#x00a0;<kbd>trigexpandplus</kbd> и <kbd>trigexpandtimes</kbd>&#x00a0;— отвечают соответственно за применение формул сумм углов и кратных углов. То есть в примере выше сначала сработал флаг <kbd>trigexpandplus</kbd>, а затем&#x00a0;<kbd>trigexpandtimes</kbd>. Эти флаги по умолчанию установлены, что и видно из примера.</p>
<p>Кроме всего уже упомянутого, есть еще флаги <kbd>trigsign</kbd> и <kbd>triginverses</kbd>. Первый принимает традиционные два значения (по умолчанию&#x00a0;<kbd>true</kbd>) и регулирует вынос знака за пределы тригонометрической функции, то есть, к примеру, <kbd>sin(–x)</kbd> упростится до <kbd>–sin(x)</kbd>, а <kbd>cos(–x)</kbd>&#x00a0;— до <kbd>cos(x)</kbd>. Флаг <kbd>triginverses</kbd>&#x00a0;— трехзначный, и умолчательное его значение равно <kbd>all</kbd>. Он отвечает за обработку сочетаний вида <kbd>sin(asin(x))</kbd> или <kbd>atan(tan(x))</kbd>. Значение <kbd>all</kbd> позволяет раскрывать эти сочетания в обоих направлениях (напомню, что при этом часть корней будет теряться); значение <kbd>true</kbd> оставляет разрешенным раскрытие только вида <kbd>sin(asin(x))</kbd>, то есть блокирует вариант с потерями периодических значений; а случай <kbd>false</kbd> запрещает оба направления преобразований.</p>
<p>Функция, обратная <kbd>trigexpand()</kbd>, называется <kbd>trigreduce(выражение)</kbd>&#x00a0;— здесь, в полном соответствии со значением слова <kbd>reduce</kbd>, действуют формулы понижения степени. Например, применив дважды эту функцию к результату предыдущего примера, мы получим его в исходном виде.</p>
<p class="labeled-image"><a href="i/tarnavsky/3/maxima3-29.png"><img src="i/tarnavsky/3/maxima3-29-thumb.png" alt="" /></a></p>
<p>Эту функцию можно вызвать с более полным списком аргументов: <kbd>trigreduce(выражение,&#x00a0;переменная)</kbd>&#x00a0;— тогда формулы понижения степени будут применяться только по отношению к заданной переменной (переменная может быть, как и почти везде, не только отдельным символом, но и выражением).</p>
<p>Третья функция занимается уже упрощением, и зовут ее, соответственно, trigsimp(выражение). Она старается упростить любое тригонометрическое выражение, используя известные формулы, такие как sin<sup>2</sup>(<var>x</var>)&#x00a0;+&#x00a0;cos<sup>2</sup>(<var>x</var>)&#x00a0;=&#x00a0;1 и тому подобные. Для наилучшего результата ее можно комбинировать с <kbd>trigreduce()</kbd>, <kbd>ratsimp()/fullratsimp()</kbd> и <kbd>radcan()</kbd>.</p>
<p>Этим возможности Maxima по преобразованию и упрощению разнообразных выражений еще не совсем исчерпаны, но основные из них мы рассмотрели в полной мере. В следующий раз поговорим немного о применении некоторых встроенных функций, о работе с векторами, матрицами и множествами и, возможно, о работе с логикой, с уравнениями и неравенствами, а также их системами.</p>
</body>
</html>