Смекни!
smekni.com

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

Например, процедура _ON(expr) обеспечивает конвертацию алгебраического выражения expr в стилизованный формат, в котором каждое float-число представляется в виде n.m.

_ON := proc(expr) local a b c d p k, , , , , ; assign(a = cat " ",( convert(expr, 'string'), " " ,) b = {seq(convert(k, 'string'), k = 0 .. 9)}), assign(d = Search2(a, {"."})); d := [seq `if`( (a[d k[ ] − 1] = " " and a[d k[ ] + 1] = "." or a[d[k] − 1] = "." and a[d[k] + 1] = " " or type(a[d[k] + 1], 'letter') or type(a[d k[ ] − 1], 'letter') or

member(a[d k[ ] + 1], b) and member(a[d k[ ] − 1], b), NULL, d k[ ]), k = 1 .. nops( )d )];

p := [1 $ (k = 1 .. nops(d))]; for k to nops(d) do if not member(a[d k[ ] − 1], b) then a := cat(a[1 .. d k[ ] − 1], "0", a[d k[ ] .. -1]); d := p + d

elif not member(a[d k[ ] + 1], b) then a := cat(a[1 .. d k[ ] − 1], a[d k[ ] + 1 .. -1]); d := d − p

end if end do; came( )a

end proc

> R:= 8.*a + 47*I+(( .5 + 8.*a +c . d) + cos(6.*gamma + x-7.) - 3.*7^(-2.*a) + int(f(x), x=1. .. .5))/

(( 8.^a.b - .8*Pi )*sqrt( a - 3. ) + exp(8.*a - 87.*Pi + 16.*I) + array(1..2, 1..2, [[1., .2], [3., 4.]]));

0.5

0.5 + 8. a + (c d . ) + cos(6. γ + − x 7.) − 3. 7(2. a) + ⌠ f( )x dx

1.

R := 8. a + 47 I +

(((8. )a . )b − 0.8 π) a − 3. + e(8. a − 87. π + 16. I) + 1.3. 0.24.  

> _ON(R);

0.5

0.5 + 8 a + (c d . ) + cos(6 γ + − x 7) − 3 7(2 a) + ⌠ f( )x dx

1

8 a + 47 I +

(((8 )a . )b − 0.8 π) a − 3 + e(8 a − 87 π + 16 I) + 13 0.24 

При этом, результат, возвращаемый процедурой _ON, пригоден для непосредственных вычислений. Между тем, данная процедура носит описательный характер, не изменяя самой сути вычисления выражений.

Тогда как процедура Evalf(x) совместно с процедурой ffp устраняет затруднения Maple при вычислениях ряда простых радикалов х с рациональными степенями от отрицательных значений, если знаменатель их показателя – нечетное число [41-43,103,109].

Evalf := proc(E::algebraic) local a b c d h g k, , , , , , , ψ; assign(a = convert(E, 'string'), g = [ ]), assign(b = Search2(a, {")^("})); ψ := x → `if`(type(x, 'integer') or x = 0, parse(cat(convert(x, 'string'), ".")), x); if b = [ ] then nulldel(evalf(E, `if`(nargs = 2 and type(args[2], 'posint'), args[2], NULL)))

;

ψ(%)

else

for k in b do c := a[nexts(a, k, "(", 1)[-1] .. nexts(a, k, ")")[-1]]; try d := map(convert, map(parse, SLD(c, "^")), 'fraction') catch : next end try ;

if type(d[1], 'negative') and type(d[2], 'fraction') and type(denom(d[2]), 'odd') then if type(numer(d[2]), 'even') then g := [op(g), c = cat "(", [( c 3 .. -1])] else g := [op(g), c = cat "(-1)*(", [( c 3 .. -1])] end if

end if

end do;

nulldel evalf parse(( ( SUB_S(g a, )), `if`(nargs = 2 and type(args 2[ ], 'posint'), args 2[ ], NULL))); ψ (%)

end if

end proc

1.5. Базовые типы структур данных Maple-языка

Наряду с простыми данными Maple-язык поддерживает работу с наиболее распространенными структурами данных такими как последовательности, списки, множества, массивы и таблицы. Вкратце остановимся на каждой из перечисленных структур.

Последовательность (sequence) – последовательная структура, широко используемая пакетом для организации как ряда других типов структур данных, так и для разнообразных вычислительных конструкций, представляет собой базовую структуру данных и определяется конструкциями следующего весьма простого вида:

Sequence := B1, B2, B3, ..., Bn; Bj (j=1..n) – любое допустимое выражение языка

Последовательность не является ни списком, ни множеством, но она лежит в основе определения этих типов структур данных пакета. Пример: GLS:= 47, Gr, -64*L, `99n+57`, F. Структура типа последовательность выражений или просто последовательность (exprseq), как уже отмечалось, образуется (,)-оператором разделителя выражений (запятая) и представляет интерес не только в качестве самостоятельного объекта в среде Maple-языка, но и в качестве основы таких важных структур как: функциональная, список, множество и индексированная. Важным свойством данного типа структуры данных является то, что если ее элементы также последовательности, то результатом является раскрытая единая последовательность, как это иллюстрирует следующий простой пример:

> AV:= a, b, c, d, e: GS:= x, y, z: Sv:=2, 9: AG:= 1, 2, 3, AV, 4, Sv, 5, 6, GS; AG := 1, 2, 3, a, b, c, d, e, 4, 2, 9, 5, 6, x, y, z

Длина произвольной SQ-последовательности (число ее элементов) вычисляется по конструкции nops([SQ]), тогда как ее k-й элемент получаем посредством оператора выделения SQ[k]. Оператор выделения имеет весьма простой вид: Id[<Выражение>], где Id – идентификатор структуры типа массив, список, множество или последовательность; значение выражения Id[k] определяет искомый элемент структуры. Если Id не определен, то он возвращается индексированным, например:

> SQ:= V, G, S, Art, Kr, Arne: {SQ[4], nops([SQ]), R[S]}; ⇒ {6, R[S], Art}

> SQ:= [SQ]: SQ[6]:= Aarne: SQ:= op(SQ): SQ; ⇒ V, G, S, Art, Kr, Aarne

> Z:= SQ: whattype(SQ); ⇒ exprseq

> type(Z, 'exprseq');

Error, wrong number (or type) of parameters in function type > hastype(Z, 'exprseq');

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

Так как по конструкции вида SQ[k]:=<Выражение> недопустимо присвоение заданного выражения k-му элементу SQ-последовательности, то для этих целей можно воспользоваться цепочкой Maple-предложений вида: SQ:=[SQ]:SQ[k]:= <Выражение>: SQ:=op(SQ):, как это иллюстрирует второй пример последнего фрагмента. При этом, следует иметь в виду, что тип последовательности тестируется только whattype-процедурой языка, т. к. при передаче последовательности в качестве аргумента другим тестирующим функциям она рассматривается как последовательность фактических аргументов. Последние три примера предыдущего фрагмента иллюстрируют сказанное. Для прямого тестирования структур типа `expressions sequence` нами была определена процедура typeseq, описанная в книге [103] и включенная в прилагаемую к ней Библиотеку [109]. Ниже дано несколько примеров ее применения, а именно:

> typeseq("Kr",Art,6,14,"RANS",IAN,Tallinn, 'seqn'(integer, string, symbol)); ⇒ true

> typeseq(a, b, 10, 17, 'seqn'), typeseq("Kr", Art, 10, 17, "RANS", IAN, Tallinn, Vilnius, 'seqn'), typeseq(G, [a], {b}, 61, 10/17, 'seqn'('integer', 'symbol', 'list', 'set', 'fraction'));

true, true, true

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

<Выражение_1> .. <Выражение_n>

где вычисляемые выражения определяют соответственно нижнюю и верхнюю границы ран-жирования с шагом 1. В зависимости от места использования ранжированной конструкции для значений выражений допускаются значения типов {float, integer}. Особо самостоятельного значения ранжированное выражение не имеет и используется в качестве ранжирующей компоненты во многих стандартных Maple-конструкциях (последовательностные структуры, суммирование, произведение, интегрирование и др.). В качестве самостоятельного применения оператор ранжирования можно использовать, например, с ||оператором конкатенации для создания последовательностей, например:

> n:= 1: m:= 9: SL:= x||(n .. m); ⇒ SL := x1, x2, x3, x4, x5, x6, x7, x8, x9

> A||("g" .. "s"); ⇒ Ag, Ah, Ai, Aj, Ak, Al, Am, An, Ao, Ap, Aq, Ar, As

> A||("м" .. "э"); ⇒ Ам, Ан, Ао, Ап, Ар, Ас, Ат, Ау, Аф, Ах, Ац, Ач, Аш, Ащ, Аъ, Аы, Аь, Аэ

> GS(x||(1 .. 5)):= (x1*x2*x5 + sin(x4 + x5))*(x1^2 + x2^2 + x3^2 + x4^2);

GS(x1, x2, x3, x4, x5) := (x1 x2 x5 + sin(x4 + x5)) (x1 + x2 + x3 + x4)

> A||(1 .. 3)||(4 .. 7); ⇒ A14, A15, A16, A17, A24, A25, A26, A27, A34, A35, A36, A37

Из приведенного фрагмента четко прослеживается одно существенное отличие бинарного ||-оператора конкатенации от других бинарных операторов Maple-языка. Если стандартным в языке является порядок вычисления выражений «слева направо», то для ||-оператора конкатенации используется обратный ему порядок вычислений. В последнем примере вычисляется сначала правый операнд, а затем левый. Более того, из второго и третьего примеров явствует, что наряду с числовыми значениями для ранжированной конструкции допускаются и буквы английского и национальных алфавитов, закодированные в строчном формате. На ранжированных выражениях функции op и nops возвращают соответственно последовательность их левых и правых частей, и число 2 операндов, тогда как функция type идентифицирует тип таких выражений как range, например:

> op(a .. b), nops(a .. b); ⇒ a, b, 2

> type("a" .. "z", 'range'), type(1 .. 64, 'range'), type(-1 .. -6.4, 'range'); ⇒ true, true, true

Детальнее структуры типа последовательность и оператор ранжирования будут рассматриваться ниже в различных контекстах, включая иллюстративные фрагменты. Здесь же мы лишь упомянем два функциональных средства Maple-языка, преднаначенных для определения последовательностных структур данных, а именно: $-оператор и seq-функция, которые имеют соответственно следующие наиболее общего вида форматы:

V(k) $ k = p .. n; ⇒ V(p), V(p + 1), ... ,V(n) seq(V[k], k = p .. n); ⇒ V(p), V(p + 1), ... ,V(n)

где V – допустимое Maple-выражение, в общем случае зависящее от к-переменной ранжирования. Следующий простой фрагмент иллюстрирует примеры структур типа последовательности, образованные $-оператором и seq-функцией Maple-языка:

> G(h) $ h = 9.42 .. 14.99; ⇒ G(9.42), G(10.42), G(11.42), G(12.42), G(13.42), G(14.42)

> seq(G(x), x = 9.42 .. 14.99); ⇒ G(9.42), G(10.42), G(11.42), G(12.42), G(13.42), G(14.42)

> 67 $ 15; ⇒ 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67

> Gs $ h = -0.25 .. 7.99; ⇒ Gs, Gs, Gs, Gs, Gs, Gs, Gs, Gs, Gs

> cat(seq(x, x = "a" .. "z")); ⇒ "abcdefghijklmnopqrstuvwxyz"

> cat(seq(x, x = "A" .. "Z")); ⇒ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

> H:= [x, y, z, h, r, t, k, p, w, z, d]: H[s] $ s=1 .. 11; ⇒ x, y, z, h, r, t, k, p, w, z, d