Смекни!
smekni.com

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

По вызову процедуры trigsubs(<Уравнение>), где уравнение должно быть строго тригонометрическим, определяется факт его вхождения в trig-таблицу. В зависимости от {наличия|отсутствия} уравнения в таблице возвращается символьное значение {`found`|`not found`}. Процедура trigsubs работает с таблицей `trigsubs/TAB`, содержимое которой для текущего релиза можно получать по вызову eval(`trigsubs/TAB`).

По вызову процедуры trigsubs(<уравнение>, <выражение>) в случае принадлежности уравнения, заданного первым аргументом функции, trig-таблице производится подстановка его в заданное вторым аргументом выражение и возвращается результат такого редактирования; в противном случае выводится соответствующее диагностическое сообщение с рекомендациями. Следующий простой фрагмент иллюстрирует вышесказанное:

> trigsubs(cot(Pi + a*x));

cot(a x −cot(−a x), 12 cotcot a x2a x22 −  1, cossin((a xa x)), 1 + sin 2cos(2( a xa x) ), 1 − sin 2cos(2( a xa x) ),

),

 2

1 − tana x

1 , − 1 , 1 22  , 1 cot a x2  − 21 tan
a x2 , tan(a x) tan(−a x) 2 tan a x 2

( )

(e a x I + e(−I a x)) I sin 2( a x)

, ,

(a x I) (−I a x) 1 − cos(2 a x)

((e )(1 + cos(2 a x)) − (e )(1 + cos(2 a x))) sin 2( a x)

 csc 2( a x) + cot 2( a x)

> map(trigsubs, [sec(x)^2 = 1 + tan(x)^2, sin(x)^2 = 1 - cos(x)^2]); ⇒ [`found`, `found`] > map(trigsubs, [sin(x) = tan(x)*cos(x), cos(x) = cot(x)*sin(x)]);

[`not found`, `not found`]

> trigsubs(sin(2*t) = 2*cos(t)*sin(t), sin(2*t)*t + tan(t)); ⇒ 2 cos(t) sin(t) t + tan(t)

> trigsubs(cos(x + y) = cos(x)*cos(y) - sin(x)*sin(y), cos(x + y)*t - 57*cos(x + y) + 2006); Error, (in trigsubs) not found in table - use subs to over ride

Как видно из приведенного фрагмента, в случае невозможности выполнить преобразование выводится сообщение с рекомендацией воспользоваться subs-функцией.

Относительно использования eval-функции, имеющей простой формат кодирования: eval(<Выражение> {, n})

следует сделать отдельное пояснение. Под вычислением понимается подстановка вместо идентификатора приписанного ему значения, а каждый шаг в данном процессе определяет отдельный вычислительный уровень. По функции eval производится вычисление определенного ее первым фактическим аргументом выражения на его n-ом вычислительном уровне или полное вычисление выражения, если второй аргумент отсутствует. В интерактивном режиме с пакетом при вводе выражений производится их полное вычисление, как если бы к входящим в них идентификаторам применялась eval-функция. Иная ситуация имеет место, в частности, для Maple-процедур, для которых локальные переменные вычисляются только на первом уровне, как это иллюстрирует следующий весьма наглядный пример:

> Proc:=proc() local a, b, c; a:= b; b:= c; c:= d: a*b*c end proc: Proc(), eval(Proc()); ⇒ b c d, d3

Из приведенного примера видно, что при вызове Proc-процедуры вычисление локальных переменных {a, b, c} производится на первом уровне, о чем свидетельствует возвращаемый процедурой результат. Тогда как применение к вызову процедуры eval-функции обеспечивает полное вычисление процедуры. При этом, следует иметь в виду, что для полного вычисления локальных переменных могут потребоваться достаточно длинные цепочки присвоений, требующих затрат основных ресурсов ПК.

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

> Proc:= proc(x, y) local a, b, c; sqrt(a*x^2 + b*y^2 + c)*sin(a*x) + cos(b*y) + 2006 end proc: > Proc1:=proc(x, y) global a,b,c; sqrt(a*x^2 + b*y^2 + c)*sin(a*x) + cos(b*y) + 2006 end proc:

> subs([a=Pi, b=sigma, c=gamma], Proc1(x, y)); ⇒ π x2 + σ y2 + γ sin(π x) + cos(σ y) + 2006

> subs([a=Pi, b=sigma, c=gamma], Proc(x, y)); ⇒ a x2 + b y2 + c sin(a x) + cos(b y) + 2006

> subs([a=sin(z),b=x*Pi], (x,y) -> sqrt(a*x+b*y)+a*b); ⇒ (x y, ) → sin( )z x + π x y + sin( )z π x

Данная возможность позволяет использовать subs-функцию, а также рассматриваемые ниже другие средства подстановок, для целого ряда весьма полезных динамических модификаций процедур в прикладных задачах (при данном подходе базовое определение продедуры остается неизменым, модифицируясь только в точке ее вызова), для чего входящие в состав модифицируемых компонент идентификаторы при определении процедур следует указывать глобальными.

По вызову процедуры applyrule(R, V) обеспечивается применение к V-выражению правил подстановки, определяемых ее первым фактическим R-аргументом (одно правило либо их список) до тех пор, пока они допустимы. При этом, правила подстановки можно определять как уравнениями, так и в форме сложных шаблонов, допускаемых patmatchпроцедурой. Процедура applyrule эффективнее средств {subs, algsubs}, однако подобно algsubs-процедуре не производит математических преобразований обрабатываемого выражения, требуя для этих целей eval-функции. Следующий фрагмент иллюстрирует применение applyrule-процедуры для преобразования выражений:

> applyrule(x*h(x) = a*x^2 + b*x^2, x*h(x)+b*(d + x*h(x))); ⇒ a x2 + b x2 + b (d + a x2 + b x2) > algsubs(x*h(x)=a*x, x*h(x));

Error, (in algsubs) cannot compute degree of pattern in x

> applyrule((a::float*x+b::integer*y)/c::function=Avz(h), (10.17*x+64*y)/sin(x)); ⇒ Avz(h)

> applyrule((a::float*x + b::integer*y)/c::function = 4, sqrt((10.17*x + 64*y)/G(x))); ⇒ 4

> applyrule([a=b, b=c, c=d, d=e, e=f,f=g,g=h], sqrt(Art^a+Kr^b+V*c)); ⇒ Arth + Krh + V h

> T:= function: applyrule([a=b, b=a], a); ⇐ Прерванный бесконечный цикл

Warning, computation interrupted

> applyrule([a^2+b^2=Art+Kr, c::function =W(t)], sqrt(a^2+b^2)*G(x)); ⇒ Art + Kr W( )t

> applyrule([a::T^b::T = Art(x), c::T/d::T = Kr(t)], S(x)^G(y) + V(x)/H(y)); ⇒ Art(x) + Kr(t)

Для исключения зацикливаний, следует уделять особое внимание определению правил подстановок. Один из примеров фрагмента иллюстрирует простую ситуацию по зацикливанию вызова applyrule-процедуры. Вместе с тем, совместное использование средств subs, applyrule, asubs, powsubs и algsubs в сочетании с рядом других функциональных средств позволяют достаточно эффективно производить весьма интересные и важные символьные преобразования различного типа выражений.

Функциональные конструкции Maple-языка. Под функцией в Maple-языке понимается невычисляемая конструкция следующего общего вида:

<Идентификатор>(<Последовательность формальных аргументов>)

где идентификатор определяет уникальное имя функции, а последовательность допустимых Maple-выражений – список ее формальных аргументов. Примерами функций являются exp(x), sin(x), sqrt(x), AGN(x, y, z) и др. Maple-язык в качестве функций понимает любую из конструкций указанного типа, независимо от того, является ли она определенной. Рассмотренная выше функция type(<Выражение>, function) тестирует произвольное выражение Maple на предмет отношения его к типу “функция”. Как видно уже из следующего весьма простого примера:

> map(type, [F(x,y,z), sin(x), H(x, G(y), z)], 'function'); ⇒ [true, true, true] к данному (функциональному) типу Maple-язык относит как процедуру sin, так и неопределенную в его среде конструкцию указанного формата. Наряду с этим, тестирующая type-функция позволяет идентифицировать не только собственно функциональный тип выражения, указанного ее первым фактическим аргументом, но и детализировать математический тип выражения-функции согласно значению ее второго фактического аргумента, а именно:

algfun – алгебраическая функция; допускается тестировать по типу коэффициентов и ве- дущим переменным;

{arctrig|arctrigh} – обратная {тригонометрическая|гиперболическая} функция; допускается тестирование по ведущим переменным;

{evenfunc|oddfunc} – {четная|нечетная} функция; допускается тестировать по ведущим переменным;

radalgfun – алгебраическая функция, определенная в терминах RootOf и радикалов; до- пускается тестирование по ведущим переменным и типам коэффициентов; radfunextn – алгебраическое функциональное расширение в терминах радикалов; radfun – радикальная функция; допускается тестирование по ведущим переменным и ти- пам коэффициентов;

mathfunc – математическая функция; тестируется любая функция из приложения 8 [12]; {trig|trigh} – {тригонометрическая|гиперболическая} функция; допускается тестирование по ведущим переменным.

При этом, алгебраическим полагается Maple-выражение одного из следующих типов:

integer fraction float string indexed `+` `*` `^` `**` series function `!` `.` uneval

а под ведущей xj-переменной произвольной F(x1, ..., xn)-функции такая переменная, на которой имеет место следующее определяющее соотношение:

(∃x`j) (∃x``j) (x`j≠x``j → F(x1, ..., x`j , ..., xn) ≠ F(x1, ..., x``j ,..., xn)) (j = 1 .. n)

Следующий фрагмент иллюстрирует применение этих значений в качестве 2-го аргумента type-функции для тестирования типов функций, указанных ее 1-м аргументом: