Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 84 из 135)

> [radsimp(3^(1/2) + 2/(2 + sqrt(3))), radsimp(3^(1/2) + 2/(2 + sqrt(3)), 'ratdenom')];

 22 + 3 + 35, −(2 3 + 5 () −2 + 3 )

> [radsimp(sqrt(x) + a/(b + sqrt(x))), radsimp(sqrt(x) + a/(b + sqrt(x)), 'ratdenom')];

 x bb + + xx + a, − ( x b + −x + b2 + a)x(b − x ) 

В определенной мере к simplify-процедуре примыкает и функция convert(W, <Форма>), обеспечивающая конвертацию W-выражения из одной в другую форму, определяемую вторым аргументом функции. Некоторые ее дополнительные возможности по конвертации выражений будут рассмотрены ниже. Функция convert может использоваться в сочетании как с рассмотренной simplify-процедурой, так и с рассматриваемыми ниже другими средствами Maple-языка для упрощения различного рода выражений.

По функции с форматом кодирования expand(<Выражение> {, V1,V2,...,Vn}) производится раскрытие указанного ее первым фактическим аргументом выражения на суммы и термы некоторых других типов. Первой попыткой функции является раскрытие произведений в суммы, что характерно, в первую очередь, для полиномов; для полиномиальных дробей такому раскрытию подвергаются только их числители. Для многих математических функций (sin, cos, tan, sinh, cosh, tanh, det, erf, exp, factorial, GAMMA, ln, int, max, min, Psi, binomial, sum, product, limit, bernoulli, euler, signum, abs, кусочно-определенных и др.) expand-функция обеспечивает стандартные формы раскрытия. При необходимости запрета на раскрытие каких-либо Vk-подвыражений раскрываемого по expand-функции выражения следует кодировать их в качестве ее необязательного второго аргумента – последовательности подвыражений. При необходимости запрета на раскрытие всех входящих в раскрываемое выражение функций используется frontend-функция в конструкции вида frontend(expand, [Выражение]). Следующий фрагмент иллюстрирует вышесказанное:

> expand(cos(x+y+z) - sin(x+y+z)), expand((n^3 + 52*n^2 - 57*n + 10)*GAMMA(n + 3)); cos(x) cos(y) cos(z) − cos(x) sin(y) sin(z) − sin(x) sin(y) cos(z) − sin(x) cos(y) sin(z) − sin( )x cos( )y cos( )z + sin( )x sin( )y sin( )z − cos( )x sin( )y cos( )z

− cos( )x cos( )y sin( )z , n6 Γ(n) + 55 n5 Γ(n) + 101 n4 Γ(n) − 57 Γ(n n) 3 − 84 Γ(n n) 2 + 20 Γ(n n) > expand((x + y)^3 - 3*(x - y)^2 + 10*(x+y)); ⇒ x3+3 x2y+3xy2 y3 - 3x2 + 6xy -3y2 +10x+10y

> expand((z + 2)^2*((x + y)^2 - 3*(x - y)^2 + 10*(x + y)), x + y, x - y);

z2 (x + y)2 − 3 z2 (x − y)2 + 10 z2 x + 10 z2 y + 4 z (x + y)2 − 12 z (x − y)2 + 40 z x

+ 40 z y + 4 (x + y)2 − 12 (x − y)2 + 40 x + 40 y

> expand(cos(x + y)*(x + 2)^2), frontend(expand, [(cos(x + y)*(x + 2)^3)]);

cos( )x cos( )y x2 + 4 cos( )x cos( )y x + 4 cos( )x cos( )y − sin( )x sin( )y x2

− 4 sin( )x sin( )y x − 4 sin( )x sin( )y , cos(x + y x) 3 + 6 cos(x + y x) 2 + 12 cos(x + y x) + 8 cos(x + y)

Приведенный фрагмент достаточно прозрачен и особых пояснений не требует. Следует отметить, что simplify-процедура является наиболее важным упрощающим средством только на первый взгляд. В процессе проводимого ею упрощения не всегда достигается желаемый результат. Более того, в ряде случаев упрощенное выражение оказывается даже менее приемлемым для последующей обработки, чем исходное. В этом плане более предпочтительной оказывается именно expand-функция, раскрывающая выражение на термы, совокупность которых значительно более удобна для последующих упрощений и преобразований.

Для обеспечения дифференцированного управления режимом раскрытия выражений предназначены две функции expandoff и expandon, имеющие единый формат кодирования, а именно:

expand{off|on}({Id_1, Id_2, ..., Id_n})

возвращающие NULL-значения и позволяющие соответственно {запрещать|разрешать} раскрытие функций, указанных последовательностью их идентификаторов (Id_k) в качестве фактического аргумента функции. В случае же вызова функции expand{off|on}() описанное действие по санкционированию раскрытия функций expand-функцией распространяется на все функции текущего сеанса, исключая пользовательские функции.

Следующий прозрачный фрагмент иллюстрирует применение указанных функций:

> P:= x -> (x + 10)^3 - sin(3*x): expand(P(y)); y3 + 30 y2 + 300 y + 1000 − 4 sin( )y cos( )y 2 + sin( )y

> expandoff(sin): expand(P(z)); ⇒ z3 + 30 z2 + 300 z + 1000 − sin(3 z)

> expand(sin(3*x)), expand(expandon()), expandon(), map(expand, [P(h), sin(3*t)]); sin(3 x), expandon( ),

[h3 + 30 h2 + 300 h + 1000 − 4 sin(h) cos( )h 2 + sin(h), 4 sin( )t cos( )t 2 − sin( )t ]

> P:= x -> (x + 10)^3 + sin(3*x)*exp(x + y): expandoff(): expand(P(t));

t3 + 30 t2 + 300 t + 1000 + 4 e(t + y) sin( )t cos( )t 2 − e(t + y) sin( )t

Данный фрагмент иллюстрирует также remember-свойство expand-функции, состоящее в том, что раз возвратив разложение выражения, функция будет помнить его, даже если наложен запрет на разложение входящих в него функций пакета. В значительной мере это весьма полезное свойство, однако оно в определенной мере не согласуется с функцией expandoff, запрещающей разложение заданных функций Maple-языка.

При использовании {expandoff|expandon}-функции следует иметь в виду, что в текущем сеансе работы с ядром она имеет однократное действие (причины этого лежат в свойстве remember функции expand) и попытки ее повторного использования или инициирующих ее конструкций приводят к ошибочной ситуации, как показано в следующем фрагменте. Ситуация разрешается, в частности, после выполнения restart-предложения.

> expand(sin(3*x)); expand(expandoff()): expandoff(sin): [expand(sin(3*x)), expand(sin(4*x)), expand(cos(3*x))];

4 sin( )x cos( )x 2 − sin( )x [4 sin( )x cos( )x 2 − sin( )x , sin 4( x), 4 cos( )x 3 − 3 cos( )x ] > expandoff(cos); expand(expandoff()):

Error, wrong number (or type) of parameters in function expand

> restart: expand(expandoff()): expandoff(cos): expand(cos(3*x)); ⇒ cos(3 x)

Поэтому в случае необходимости рекомендуется сразу определять функции, не подлежащие раскрытию по expand-функции, что устранит ошибочные ситуации.

Наконец, пассивная Expand(v)-функция представляет собой шаблон expand-функции, используемый в конъюнкции с evala-функцией или в mod-конструкциях. По конструкции вида evala(Expand(v)) производится раскрытие произведений в произвольном v-выражении, которое может включать алгебраические числа и/или RootOf-процедуры. Тогда как по конструкции Expand(v) (mod p) производится раскрытие произведений над целыми по (mod p) и v-выражение может содержать вызовы RootOf-процедур. Например:

> Expand((57*x + 3)^2*(x^2 - 2*x + 52)) mod 5; ⇒ 4 x4 + 4 x3 + 3 x2 + x + 3

> evala(Expand(RootOf(x^2 - 3*x - 10)^2)); ⇒ 10 + 3 RootOf(_Z2 - 3 _Z - 10)

Обратной к expand является factor(V{, F})-процедура, возвращающая результат факторизации V-выражения полиномиального типа с целыми, рациональными, комплексными или алгебраическими числовыми коэффициентами. При этом, если V – отношение полиномов, то производится факторизация отдельно для числителя и знаменателя. Второй необязательный F-аргумент функции определяет тип числового поля, над которым должна производиться факторизация; по умолчанию выбирается поле, определяемое типом коэффициентов полинома. При значениях для F-аргумента real или complex типа производится соответственно float- или complex-факторизация. В этом случае в качестве V-выражения должен выступать полином от одной переменной или их отношение. Если в качестве факторизуемого V-выражения выступает список, множество, диапазон выражений, ряд, отношение либо функция, то факторизация применяется рекурсивно к его компонентам. Следующий прозрачный фрагмент иллюстрирует некоторые варианты применения factor-процедуры для факторизации выражений:

> Digits:= 6: P:= x*4 - 57*x^3 + 52*x^2 - 10*x + 32: factor(P); ⇒ -6 x - 57 x3 + 52 x2 + 32

> map2(factor, P, [real, complex]); factor([x^2 - 3*x + 52, x^2 - 10*x + 32], 'complex');

[−57. (x − 1.20919 ) (x2 + 0.296908 x + 0.464281 ),

−57. (x + 0.148454 + 0.665013 I) (x + 0.148454 − 0.665013 I) (x − 1.20919 ])

[(x − 1.50000 + 7.05337 I) (x − 1.50000 − 7.05337 I),

(x − 5.00000 + 2.64575 I) (x − 5. − 2.64575 I)]

> P1:= x^2*y^2 - 18*x^2*y + 81*x^2 - 4*x*y^2 + 72*x*y - 324*x + 4*y^2 - 72*y + 324:

> P2:= x^2*y^2 - 4*x^2*y + 4*x^2 - 2*x*y^2 + 8*x*y - 8*x + y^2 - 4*y + 4: factor(P1/P2);

(x − 2)2

(y − 2)2

> factor([G(P1/P2) .. H(P2/P1), P1 <> P2]);

G ((yy − − 29))22 ((xx − − 21))22  .. H ((yy − − 29))22 ((xx − − 21))22 , (y − 9)2 (x − 2)2 ≠ (y − 2)2 (x − 1)2 

Если в качестве значения F-аргумента выступают RootOf-процедура, список либо множество RootOf-процедур, радикал, их список либо множество, то факторизация производится над соответствующим числовым алгебраическим полем.

Наконец, по процедуре factors(V{, F}) производится факторизация полинома от нескольких переменных с действительными или комплексными коэффициентами над рациональным алгебраическим числовым полем. В отличие от factor-процедуры, допускающей любое V-выражение, для factors-процедуры в качестве ее первого аргумента должен выступать только V-полином, а возвращается списочная структура следующего вида:

n k[j]

[G, [[M[1], k[1]], [M[2], k[2]], ... [M[n], k[n]]]] ; V = G * ∏ M[j] j 1= где M[j] и k[j] – соответственно фактор (сомножитель) и его кратность. Данная структура достаточно удобна при использовании результатов факторизации в задачах программирования, т.к. позволяет легко выделять составляющие ее компоненты. Сказанное о втором необязательном F-аргументе factor-процедуры переносится и на factors-процедуру. Пассивная функция Factors(V{, F}) представляет собой шаблон factors-процедуры, используемый в конъюнкции с evala-функцией либо в mod-конструкции аналогично тому, как это было описано для Factor-функции с очевидными изменениями. Следующий фрагмент иллюстрирует использование рассмотренных средств факторизации: