Error invalid terms in product

Error, invalid terms in product Description Examples See Also Description For users of Maple 15 and earlier versions: This error occurs when one or both of the operands that form the type arithmetic expression are of a type that is not allowed to be...

Error, invalid terms in product

Description

Examples

See Also

Description

For users of  Maple 15 and earlier versions: This error occurs when one or both of the operands that form the* type arithmetic expression are of a type that is not allowed to be multiplied.


Examples

Example 1
In the following example, one of the operands in the arithmetic expression is a string, for arithmetic operations are not allowed.


a ⋅b

Error, invalid terms in product: a

Solution:

Changing the string, to the variable a, corrects this error.


a⋅b

a⁢b

(2.1)

Example 2

In the following example, a space between print and the left parenthesis implies multiplication between the two, which causes an error.


Az≔.15:


if Az < .25 then print O.K else printN.G end if&semi;

Error, invalid terms in product: O.K

Solution:

Removing the space between print and the left parenthesis corrects this error.


if Az < .25 then printO.K else printN.G end if&semi;

O.K

(2.2)


See Also

arithmetic, binary infix operators in Maple, type

Ввожу формулы большие для расчетов, все хорошо было, а в конце вот что выдали-с=(

Error, (in simpl/reloprod) invalid terms in product

Подскажите, пжлста, что плохого я сделала? Прикрепить файл не смогла — 65 кб. Может так дойдет

> restart;

> g[11][i] := E[1][i]/(1-nu[12][i]*nu[21][i]);

> g[22][i] := E[2][i]/(1-nu[12][i]*nu[21][i]);

> g[12][i] := nu[12][i]*g[22][i] = nu[21][i]*g[11][i];

> g[66][i] := G[12][i];

> g[rr][i] := g[11][i]*cos(alpha)^4+g[22][i]*sin(alpha)^4+(2*g[12][i]+4*g[66][i])*sin(alpha)^2*cos(alpha)^2;

> g[`&varphi;&varphi;`][i] := g[11][i]*sin(alpha)^4+g[22][i]*cos(alpha)^4+(2*g[12][i]+4*g[66][i])*sin(alpha)^2*cos(alpha)^2;

> g[`r&varphi;`][i] := (g[11][i]+g[22][i]-4*g[66][i])*sin(alpha)^2*cos(alpha)^2+g[12][i](sin(alpha)^4+cos(alpha)^4);

> g[ss][i] := (g[11][i]+g[22][i]-4*g[66][i])*sin(alpha)^2*cos(alpha)^2+g[66][i](sin(alpha)^2-cos(alpha)^2);

> G[rr] := sum(g[rr][i]*h[p][i], i = 1 .. 4);

> G[`&varphi;&varphi;`] := sum(g[`&varphi;&varphi;`][i]*h[p][i], i = 1 .. 4);

> G[`r&varphi;`] := sum(g[`r&varphi;`][i]*h[p][i], i = 1 .. 4);

> G[ss] := sum(g[ss][i]*h[p][i], i = 1 .. 4);

> h[p][i] := h[i]/(sum(h[i], i = 1 .. 4));

> E[r] := G[rr]-G[`r&varphi;`]^2/G[`&varphi;&varphi;`];

Error, (in simpl/reloprod) invalid terms in product

> E[`&varphi;`] := G[`&varphi;&varphi;`]-G[`r&varphi;`]^2/G[rr];

Error, (in simpl/reloprod) invalid terms in product

> nu[`r&varphi;`] := G[`r&varphi;`]/G[`&varphi;&varphi;`];

Error, (in simpl/reloprod) invalid terms in product

> nu[`&varphi;r`] := G[`r&varphi;`]/G[rr];

Error, (in simpl/reloprod) invalid terms in product

> G[`r&varphi;s`] := G[ss];

>

Содержание

  1. Exponenta.ru
  2. формулы сложные?
  3. формулы сложные?
  4. pmi432 / LR05 / Books / Аладьев — Основы программирования в Maple, 2006

Exponenta.ru

Образовательный математический сайт

формулы сложные?

Модератор: Admin

формулы сложные?

Сообщение tasha » Сб ноя 19, 2011 5:59 pm

Ввожу формулы большие для расчетов, все хорошо было, а в конце вот что выдали-с=(
Error, (in simpl/reloprod) invalid terms in product
Подскажите, пжлста, что плохого я сделала? Прикрепить файл не смогла — 65 кб. Может так дойдет
> restart;
> g[11][i] := E[1][i]/(1-nu[12][i]*nu[21][i]);
> g[22][i] := E[2][i]/(1-nu[12][i]*nu[21][i]);
> g[12][i] := nu[12][i]*g[22][i] = nu[21][i]*g[11][i];
> g[66][i] := G[12][i];

> g[rr][i] := g[11][i]*cos(alpha)^4+g[22][i]*sin(alpha)^4+(2*g[12][i]+4*g[66][i])*sin(alpha)^2*cos(alpha)^2;
> g[`ϕϕ`][i] := g[11][i]*sin(alpha)^4+g[22][i]*cos(alpha)^4+(2*g[12][i]+4*g[66][i])*sin(alpha)^2*cos(alpha)^2;
> g[`rϕ`][i] := (g[11][i]+g[22][i]-4*g[66][i])*sin(alpha)^2*cos(alpha)^2+g[12][i](sin(alpha)^4+cos(alpha)^4);
> g[ss][i] := (g[11][i]+g[22][i]-4*g[66][i])*sin(alpha)^2*cos(alpha)^2+g[66][i](sin(alpha)^2-cos(alpha)^2);
> G[rr] := sum(g[rr][i]*h[p][i], i = 1 .. 4);
> G[`ϕϕ`] := sum(g[`ϕϕ`][i]*h[p][i], i = 1 .. 4);
> G[`rϕ`] := sum(g[`rϕ`][i]*h[p][i], i = 1 .. 4);
> G[ss] := sum(g[ss][i]*h[p][i], i = 1 .. 4);
> h[p][i] := h[i]/(sum(h[i], i = 1 .. 4));
> E[r] := G[rr]-G[`rϕ`]^2/G[`ϕϕ`];
Error, (in simpl/reloprod) invalid terms in product
> E[`ϕ`] := G[`ϕϕ`]-G[`rϕ`]^2/G[rr];
Error, (in simpl/reloprod) invalid terms in product
> nu[`rϕ`] := G[`rϕ`]/G[`ϕϕ`];
Error, (in simpl/reloprod) invalid terms in product
> nu[`ϕr`] := G[`rϕ`]/G[rr];
Error, (in simpl/reloprod) invalid terms in product
> G[`rϕs`] := G[ss];
>

Источник

pmi432 / LR05 / Books / Аладьев — Основы программирования в Maple, 2006

4.2. Формальные и фактические аргументы Maple —

Формальный аргумент процедуры в общем случае имеет вид Id > :: Тип >, т. е. Id -идентифи- катор с приписанным ему типом , который не является обязательным. В случае определения типированного формального аргумента при передаче процедуре в момент ее вызова фактического аргумента, последний проверяется на соответствие типу формального аргумента. При несовпадении типов идентифицируется ошибочная ситуация с выводом соответствующей диагностики. Совершенно иная ситуация имеет место при несовпадении числа передаваемых процедуре фактических аргументов числу ее формальных аргументов: ( 1 ) в случае числа фактических аргументов, меньшего определенного для процедуры числа формальных аргументов, как правило, идентифицируется ошибочная ситуация типа “ Error, (in Proc ) Proc uses a n th argument Id >, which is missing ” , указывающая на то, что Proc -процедуре было передано меньшее число фактических аргументов, чем имеется формальных аргументов в ее определении; где Id — идентификатор первого недостающего n -го фактического аргумента; ( 2 ) в случае числа фактических аргументов, большего определенного для процедуры числа формальных аргументов, ошибочной ситуации не идентифицируется и лишние аргументы игнорируются. Между тем, и в первом случае возможен корректный вызов. Это будет в том случае, когда в теле процедуры не используются формальные аргументы явно . Следующий простой фрагмент хорошо иллюстрирует вышесказанное:

nargs, [args] end proc: Proc(5, 6, 7, 8, 9, 10), Proc(5), Proc(), Proc(5, 6, 7);

6, [5, 6, 7, 8, 9, 10], 1, [5], 0, [], 3, [5, 6, 7]

a*b*c end proc: Proc(5, 6, 7), Proc(5, 6, 7, 8, 9, 10); 210, 210

Error, (in Proc) Proc uses a 2nd argument, b, which is missing

> AVZ:= proc(x::integer, y, z::float) evalf(sqrt(x^3 + y^3)/(x^2 + y^2)*z) end proc:

Error, AVZ expects its 1st argument, x, to be of type integer, but received 20.06

Error, (in AVZ) AVZ uses a 3rd argument, z (of type float), which is missing

> [ AVZ (64, 42, 19.42), AVZ (59, 42, 19.42, 78, 52)]; [1.921636024, 1.957352295]

В момент вызова процедуры с передачей ей фактических выражений для ее соответствующих формальных аргументов первые предварительно вычисляются и их значения передаются в тело процедуры для замещения соответствующих им формальных аргументов, после чего производится вычисление составляющих тело Maple -предложений с возвратом значения последнего вычисленного предложения, если не было указано противного. В случае наличия в определении процедуры типированных формальных аргументов элементы последовательности передаваемых при ее вызове фактических значений проверяются на указанный тип и в случае несовпадения инициируется ошибочная ситуация, в противном случае выполнение процедуры продолжается. В качестве типов формальных аргументов процедуры используются любые из допустимых языком и тестируемых функцией type и процедурой whattype . В случае использования нетипированного формального аргумента рекомендуется все же указывать для него anything -тип, информируя других пользователей процедуры о том, что для данного формального аргумента допускаются значения любого типа, например, кодированием заголовка процедуры в виде proc (X:: integer , Y:: anything ) .

В качестве формальных аргументов могут выступать последовательности допустимыхе Maple — выражений, типированных переменных, либо пустая последовательность. Типированная переменная кодируется в следующем формате:

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

> A:=proc(a::integer, b::float) a*b end proc: A(64, 42);

Error, invalid input: A expects its 2nd argument, b, to be of type float, but received 42

«invalid input: %1 expects its %-2 argument, %3, to be of type %4, but received %5»

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

> A1:=proc(a::numeric, b::numeric) local a1, b1; assign(a1=a, b1=b); if not type(a, ‘integer’) then a1:=round(a) end if; if not type(b, ‘float’) then b1:=float(b) end if; a*b end proc: A1(64, 42), 17*A1(10/17, 59); 2688, 590

Большинство процедур нашей библиотеки [103] использует именно подобный подход программной обработки получаемых фактических аргументов на их допустимость и, по возможности, производятся допустимые корректировки. Это существенно повышает устойчивость процедур относительно некорректных фактических аргументов.

При организации процедур роль типированных формальных аргументов не ограничивается только задачами проверки входной информации, но несет и ряд других важных нагрузок. В частности, использование uneval -типа для формального аргумента позволяет вне процедуры проводить его модификацию ( т.е. обновлять на « месте » Maple — объект, определенный вне тела процедуры под этим идентификатором ) как это иллюстрирует нижеследующий фрагмент:

A := proc ( L :: list , a :: anything ) assign(‘ L ‘ = subs( a = NULL , L )) end proc

> L:=[64, 59, 39, 44, 10, 17]; A(L, 64); L := [64, 59, 39, 44, 10, 17] Error, (in assign) invalid arguments

A1 := proc ( L :: uneval , a :: anything ) if not type( L , ‘ symbol ‘) then

error «1st argument must be symbol but had received %1» , whattype( L ) elif type(eval( L ), <‘ list ‘, ‘ set ‘>) then assign(‘ L ‘ = subs(

[`if`( not type( a , <‘ list ‘, ‘ set ‘>), a = NULL , seq( k = NULL , k = a ))],

else error «1st argument must has type but had received %1-type» , whattype(eval( L ))

end if end proc

> A1(L, 64), L, A1(L, 59), L, A1(L, <59, 39, 44, 10, 17>), L; [59, 39, 44, 10, 17], [39, 44, 10, 17], [] > A1(AVZ, 64), AVZ;

Error, (in A1) 1st argument must has type but had received symbol-type

> A1([1, 2, 3, 4, 5, 6], 64);

Error, (in A1) 1st argument must be symbol but had received list

Попытка определить такую операцию для стандартно типированного L -аргумента в А -про- цедуре вызывает ошибку выполнения, тогда как, определив этот же L -аргумент как аргумент uneval -типа и использовав в дальнейшем обращение к нему через eval -функцию, получаем вполне корректную А1 -процедуру, обеспечивающую обновление « на месте » списка/множест-

ва L путем удаления его элементов, определенных вторым a -аргументом, в качестве которого может выступать как отдельный элемент, так и их список/множество. Проверка же на тип фактического L -аргумента производится уже программного в самой процедуре; при этом, проверяется не только на тип < list , set >, но и на получение идентификатора объекта, а не его значения ( т.е. в качестве фактического L -аргумента должно выступать имя списка/множества ). Данный прием может оказаться весьма полезным в практическом программировании, именно он используется рядом процедур нашей библиотеки [103].

Для организации процедуры наряду с предложениями, описывающими непосредственный алгоритм решаемой задачи ( а в ряде случаев и для обеспечения самого алгоритма ), Maple -язык предоставляет ряд важных средств, обеспечивающих функции, управляющие выполнением процедуры. В первую очередь, к ним можно отнести переменные args и nargs , возвращающие соответственно последовательность переданных процедуре фактических аргументов и их коли — чество . Оба эти средства имеют смысл только в рамках процедуры, а по конструкциям вида args <| [n] | [n..m] >можно получать < последовательность фактических аргументов | n — й аргумент |

аргументы с n — го по m — й включительно > соответственно. Тогда как nargs -переменная возвращает количество полученных процедурой фактических аргументов. Назначение данных средств достаточно прозрачно и обусловливает целый ряд их важных приложений при разработке пользовательских процедур. В первую очередь, это относится к обработке получаемых процедурой фактических аргументов. В частности, nargs -переменная необходима с целью обеспечения определенности выполнения вычислений в случае передачи процедуре неопределенного числа аргументов. Следующий простой фрагмент иллюстрирует сказанное:

> SV:= proc() product(args[k], k= 1 .. nargs)/sum(args[k], k= 1 .. nargs) end proc: > 137*SV(42, 47, 62, 67, 89, 96, 350, 39, 44, 59, 64); 22698342960272179200

> GN:= proc() [nargs, [args]] end proc: GN(V, G, S, A, Art, Kr);

[6, [V, G, S, A, Art, Kr]]

> map(whattype, [59, 17/10, ln(x), 9.9, «RANS»]);

[integer, fraction, function, float, string]

> Arg_Type:= proc() map(whattype, [seq(args[k], k= 1 .. nargs)]) end proc:

> Arg_Type(59, 17/10, ln(x), 9.9, «RANS»);

[integer, fraction, function, float, string]

> Arg_Type:= proc() map(whattype, [args[k]$k= 1 .. nargs]) end proc:

> Arg_Type(59, 17/10, ln(x), 9.9, «RANS»);

[integer, fraction, function, float, string]

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

что оказывается весьма удобным механизмом для организации процедур, ориентированных, в первую очередь, на задачи символьных вычислений и обработки [9-14,39].

Дополнительно к переменным args и nargs можно отметить еще одну важную переменную procname , возвращающую имя процедуры ее содержащей. В целом ряде случаев данная переменная оказывается весьма полезной, в частности, при возвращении вызова процедуры не — вычисленным . С этой целью используется конструкция формата ‘procname( args )’ . Многие пакетные процедуры возвращают результат именно в таком виде, если не могут решить задачу. Ряд процедур и нашей библиотеки [103] поступают аналогичным образом. Между тем, переменная может procname использоваться и в других полезных приложениях. Следующий фрагмент иллюстрирует применение указанной переменной как для организации возврата вызова процедуры невычисленным, так и для вывода соответствующего сообщения:

if nargs ≤ 6 then

WARNING(«%1(%2)=%3», procname , seqstr(args), `+`(args)/nargs ) else ‘procname (args)’

end if end proc

> AVZ(64, 59, 39, 44, 10, 17);

Warning, AVZ(64, 59, 39, 44, 10, 17)=233/6

> AVZ(64, 59, 39, 44, 10, 17, 6); AVZ(64, 59, 39, 44, 10, 17, 6)

Процедура AVZ при получении не более 6 фактических аргументов выводит соответствующее сообщение, описывающее вызов процедуры и его результат, тогда как в противном случае вызов процедуры возвращается невычисленным . Исходные тексты процедур нашей библиотеки, прилагаемой к книге [103], предоставляют неплохой иллюстративный материал по использованию переменных args , nargs и procname процедуры в различных ситуациях.

4.3. Локальные и глобальные переменные Maple —

Используемые в теле процедуры переменные по области определения делятся на две группы: глобальные ( global ) и локальные ( local ). Глобальные переменные определены в рамках всего текущего сеанса работы с ядром пакета и их значения доступны как для использования, так и для модификации в любой момент и в любой Maple -конструкции, где их применение корректно. Для указания переменной глобальной ее идентификатор кодируется в global -секции определения процедуры, обеспечивая процедуре доступ к данной переменной. В этой связи во избежание возможной рассинхронизации вычислений и возникновения ошибочных ситуаций рекомендуется в качестве глобальных использовать в процедурах только те переменные, значения которых ими не модифицируются, а только считываются. В противном случае не исключено возникновение отмеченных ситуаций, включая и непредсказуемые. Следующий пример иллюстрирует некорректность определения в процедуре глобальной х -переменной:

> x:=64: proc(y) global x; x:=0; y^(x+y) end proc(10); evalf(2006/x); 10000000000 Error, numeric exception: division by zero

> x:=64: proc(y) global x; x:=0; y^(x+y) end proc: evalf(2006/x); 31.34375000

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

Если для переменных, используемых в определении процедуры, не определена область их действия ( local , global ), то Maple -язык классифицирует их следующим образом. Каждая переменная, получающая в теле процедуры определение по ( := )-оператору либо переменная цикла, определяемая функциями < seq , add , mul >полагается локальной ( local ), остальные полагаются глобальными ( global ) переменными. При этом, если переменные for -цикла не определены локальными явно, то выводится предупреждающее сообщение вида “ Warning, `k` is implicitly declared local to procedure `P` ” , где k и P – переменная цикла в процедуре P соответственно. Тогда как для функций sum и product переменные цикла рассматриваются глобаль — ными , не выводя каких-либо сообщений, что предполагает их явное определение в local -сек- ции. Однако вне зависимости от наличия предупреждающих сообщений рекомендуется яв — но указывать локальные и глобальные переменные, что позволит не только избегать ошибок выполнения, но и более четко воспринимать исходный текст процедуры. Следующий фрагмент иллюстрирует вышесказанное:

> G:= 2: A:= proc(n) V:=64: [args, assign(‘G’, 5), assign(‘V’, 9), assign(cat(H, n), `h`)] end proc:

Warning, `V` is implicitly declared local to procedure `A`

> [A(99), G, V, A(10), whattype(H9), H9]; [[99], 5, 9, [10], symbol, H9]

> k:= 64: H:= proc() product(args[k], k=1 .. nargs)/sum(args[k], k=1 .. nargs) end proc:

> [k, H(42, 47, 62, 67, 96, 89, 10, 17, 4), k];

Error, (in H) invalid subscript selector

> k:= 64: H:= proc() local k; product(args[k], k=1 .. nargs)/sum(args[k], k=1 .. nargs) end proc: > [k, H(42, 47, 62, 67, 96, 89, 10, 17, 4), k]; [64, 109772628480, 64]

> G:=proc() [seq(args[k],k=1..nargs), mul(args[n], n=1..nargs)/add(args[p], p=1..nargs)] end proc:

> k:=64: n:= 95: p:= 99: G(1, 2, 3, 4, 5, 6, 7, 8, 9): [k, n, p];

> k:=64: P:= () -> [seq(args[k], k=1..nargs)]: P(1, 2, 3), k;

> k:=64: P:= () -> [add(args[k], k=1..nargs)]: P(1, 2, 3), k;

> k:=64: P:= () -> [mul(args[k], k=1..nargs)]: P(1, 2, 3), k;

> k:=64: P:= () -> [sum(args[k], k=1..nargs)]: P(1, 2, 3), k;

Error, (in P) invalid subscript selector

> k:=64: P:= () -> [product(args[k], k=1..nargs)]: P(1, 2, 3), k;

Error, (in P) invalid subscript selector

> k:=64: P:=proc() for k to nargs do end do end proc: P(1, 2, 3), k; 64 Warning, `k` is implicitly declared local to procedure `P`

Таким образом, в указанных случаях соответствующие переменные процедуры при ее вычислении неявно декларируются локальными с выводом или без предупреждающих сообщений. С другой стороны, глобальные переменные даже без их явного декларирования в global -сек- ции можно генерировать в рамках процедуры, как это иллюстрирует первый пример предыдущего фрагмента. Делать это позволяет процедура assign . Однако работа с такими глобаль — ными переменными чревата непредсказуемыми последствиями. Таким образом, практика программирования в среде Maple -языка рекомендует следовать следующим двум правилам определения области действия переменных:

( 1 ) глобальными определять переменные лишь используемые в режиме ” чтения ” ; ( 2 ) локальные переменные определять явно в local — секции процедуры.

Использование данных правил позволит избежать многих ошибок, возникающих лишь в момент выполнения M aple -программ, синтаксически и семантически корректных, но не учитывающих специфики механизма использования языком глобальных и локальных переменных. А именно: если глобальная переменная имеет областью определения весь текущий сеанс работы с пакетои, включая тело процедуры ( глобально переопределять ее можно внутри любой Maple — кон — струкции ), то локальная переменная областью определения имеет лишь тело процедуры и вне процедуры она полагается неопределенной, если до того не была определена вне процедуры глобально переменная с тем же идентификатором. Данный механизм имеет глубокий смысл, ибо позволяет локализовать действия переменных рамками процедуры ( в общем случае черного ящика ), не влияя на общий вычислительный процесс текущего сеанса работы с пакетом. Примеры предыдущего фрагмента наглядно иллюстрируют практическую реализацию описанного механизма локализации переменных в Maple- процедурах.

По assign -процедуре в теле процедур можно назначать выражения как локальным ( заданным явно ), так и глобальным ( заданным явно либо неявно ) переменным. Однако, здесь имеется одно весьма существенное отличие. Как известно, пакет не допускает динамического генерирования имен в левой части ( := )-оператора присваивания, тогда как на основе assign -процедуры это возможно делать. Это действительно существенная возможность, весьма актуальная в целом ряде задач практического программирования [103]. Между тем, если мы по процедуре assign в теле процедуры будем присваивать выражения локальным переменным и сгенерированным одноименным с ними переменным, то во втором случае присвоения производятся именно глобальным переменным, не затрагивая локальных . Нижеследующий пример весьма наглядно иллюстрирует вышесказанное.

> restart; V42, G47:= 10, 17: proc() local V42, G47; assign(V42=64, G47=59); assign(cat(V, 42)=100, cat(G, 47)=200); [V42, G47] end proc(), [V42, G47]; [64, 59], [100, 200]

Таким образом, данное обстоятельство следует учитывать при работе с динамически генерируемыми переменными в теле процедур.

Следует еще раз отметить, что для предложений присвоения в процедурах в целом ряде случаев использование assign -процедуры является единственно возможным подходом. Однако, при таком подходе в общем случае требуется, чтобы левая часть уравнения x=a в assign(x=a) была неопределенным именем, т.е. для нее должно выполняться соотношение type (x, ‘symbol’) = true . И здесь вполне допустимо использование конструкций следующего общего формата:

assign(op([unassign(‘ Имя > ‘), Имя > ]) = Выражение > )

При этом, для таких объектов как процедуры, модули, таблицы и массивы ( включая матрицы и векторы в смысле Maple , а не NAG ) кодирование их имен в невычисленном формате необяза —

Источник

Peter Pein

unread,

Aug 11, 2012, 12:24:42 PM8/11/12

to

sigh…

when i paste the text below into the «Mma input» part of the maplet’s

window and click «Translate» then I get a strange message:

Title reads: «Unable to translate» and the message is: «Invalid terms in

product: 1″???

My question is: why is 1 an invalid term in a product?

entering 1*1 gives no error (but there are two terms equal to 1)

TIA,

Peter

P.S: the exact copy of the input:

df[a_?NumericQ, n_Integer] :=

Block[{n0 = Ceiling[a/Pi],

ak = (-1)^(#1 + Floor[n/2]) Piecewise[{{Sin, EvenQ[n]}}, Cos][

a/#]/#^n &},

Total[N[Array[ak[#, a] &, n0]]] +

NSum[ak[k, a], {k, n0 + 1, Infinity}]]

Axel Vogt

unread,

Aug 11, 2012, 5:55:44 PM8/11/12

to

I am using Maple 15. For simple cases the translator works, but I

never used it for MMA programs (and do not know, which versions or

constructs are covered).

For the above example I get a different reply:

«(your stuff from above)»; # i.e. entred as string to Maple

convert(%, FromMma); # should do the translation

results in

Error, invalid terms in product: df(`a_?NumericQ`,n_Integer) := 1

When I remove your line breaks (but not caring for blanks),

then I get something different and readable, but nothing

that Maple understands.

4.2. Формальные и фактические аргументы Maple

процедуры

Формальный аргумент процедуры в общем случае имеет вид <Id>::<Тип>, т. е. Id-идентифи- катор с приписанным ему типом, который не является обязательным. В случае определения типированного формального аргумента при передаче процедуре в момент ее вызова фактического аргумента, последний проверяется на соответствие типу формального аргумента. При несовпадении типов идентифицируется ошибочная ситуация с выводом соответствующей диагностики. Совершенно иная ситуация имеет место при несовпадении числа передаваемых процедуре фактических аргументов числу ее формальных аргументов: (1) в случае числа фактических аргументов, меньшего определенного для процедуры числа формальных аргументов, как правило, идентифицируется ошибочная ситуация типа “Error, (in Proc) Proc uses a nth argument <Id>, which is missing, указывающая на то, что Proc-процедуре было передано меньшее число фактических аргументов, чем имеется формальных аргументов в ее определении; где Id — идентификатор первого недостающего n-го фактического аргумента; (2) в случае числа фактических аргументов, большего определенного для процедуры числа формальных аргументов, ошибочной ситуации не идентифицируется и лишние аргументы игнорируются. Между тем, и в первом случае возможен корректный вызов. Это будет в том случае, когда в теле процедуры не используются формальные аргументы явно. Следующий простой фрагмент хорошо иллюстрирует вышесказанное:

> Proc:= proc(a, b, c)

nargs, [args] end proc: Proc(5, 6, 7, 8, 9, 10), Proc(5), Proc(), Proc(5, 6, 7);

6, [5, 6, 7, 8, 9, 10], 1, [5], 0, [], 3, [5, 6, 7]

> Proc:= proc(a, b, c)

a*b*c end proc: Proc(5, 6, 7), Proc(5, 6, 7, 8, 9, 10); 210, 210

> Proc(645);

Error, (in Proc) Proc uses a 2nd argument, b, which is missing

>AVZ:= proc(x::integer, y, z::float) evalf(sqrt(x^3 + y^3)/(x^2 + y^2)*z) end proc:

>AVZ(20.06, 59, 64);

Error, AVZ expects its 1st argument, x, to be of type integer, but received 20.06

> AVZ(2006, 456);

Error, (in AVZ) AVZ uses a 3rd argument, z (of type float), which is missing

> [AVZ(64, 42, 19.42), AVZ(59, 42, 19.42, 78, 52)]; [1.921636024, 1.957352295]

Вмомент вызова процедуры с передачей ей фактических выражений для ее соответствующих формальных аргументов первые предварительно вычисляются и их значения передаются в тело процедуры для замещения соответствующих им формальных аргументов, после чего производится вычисление составляющих тело Maple-предложений с возвратом значения последнего вычисленного предложения, если не было указано противного. В случае наличия в определении процедуры типированных формальных аргументов элементы последовательности передаваемых при ее вызове фактических значений проверяются на указанный тип и в случае несовпадения инициируется ошибочная ситуация, в противном случае выполнение процедуры продолжается. В качестве типов формальных аргументов процедуры используются любые из допустимых языком и тестируемых функцией type и процедурой whattype. В случае использования нетипированного формального аргумента рекомендуется все же указывать для него anything-тип, информируя других пользователей процедуры о том, что для данного формального аргумента допускаются значения любого типа, например, кодированием заголовка процедуры в виде proc(X::integer, Y::anything).

Вкачестве формальных аргументов могут выступать последовательности допустимыхе Maple— выражений, типированных переменных, либо пустая последовательность. Типированная переменная кодируется в следующем формате:

<Переменная>::<Тип>

171

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

> A:=proc(a::integer, b::float) a*b end proc: A(64, 42);

Error, invalid input: A expects its 2nd argument, b, to be of type float, but received 42

> lasterror;

«invalid input: %1 expects its %-2 argument, %3, to be of type %4, but received %5»

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

> A1:=proc(a::numeric, b::numeric) local a1, b1; assign(a1=a, b1=b); if not type(a, ‘integer’) then a1:=round(a) end if; if not type(b, ‘float’) then b1:=float(b) end if; a*b end proc: A1(64, 42), 17*A1(10/17, 59); 2688, 590

Большинство процедур нашей библиотеки [103] использует именно подобный подход программной обработки получаемых фактических аргументов на их допустимость и, по возможности, производятся допустимые корректировки. Это существенно повышает устойчивость процедур относительно некорректных фактических аргументов.

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

A := proc (L::list, a::anything ) assign(‘L= subs(a = NULL, L)) end proc

> L:=[64, 59, 39, 44, 10, 17]; A(L, 64); L := [64, 59, 39, 44, 10, 17] Error, (in assign) invalid arguments

A1 := proc (L::uneval, a::anything ) if not type(L, ‘symbol‘) then

error «1st argument must be symbol but had received %1» , whattype(L) elif type(eval(L), {‘list‘, ‘set‘}) then assign(‘L= subs(

[`if`( not type(a, {‘list‘, ‘set‘}), a = NULL, seq(k = NULL, k = a))],

eval(L)))

else error «1st argument must has type {list, set} but had received %1-type» , whattype(eval(L))

end if end proc

> A1(L, 64), L, A1(L, 59), L, A1(L, {59, 39, 44, 10, 17}), L; [59, 39, 44, 10, 17], [39, 44, 10, 17], [] > A1(AVZ, 64), AVZ;

Error, (in A1) 1st argument must has type {list, set} but had received symbol-type

> A1([1, 2, 3, 4, 5, 6], 64);

Error, (in A1) 1st argument must be symbol but had received list

Попытка определить такую операцию для стандартно типированного L-аргумента в А-про- цедуре вызывает ошибку выполнения, тогда как, определив этот же L-аргумент как аргумент uneval-типа и использовав в дальнейшем обращение к нему через eval-функцию, получаем вполне корректную А1-процедуру, обеспечивающую обновление «на месте» списка/множест-

172

ва L путем удаления его элементов, определенных вторым a-аргументом, в качестве которого может выступать как отдельный элемент, так и их список/множество. Проверка же на тип фактического L-аргумента производится уже программного в самой процедуре; при этом, проверяется не только на тип {list, set}, но и на получение идентификатора объекта, а не его значения (т.е. в качестве фактического L-аргумента должно выступать имя списка/множества). Данный прием может оказаться весьма полезным в практическом программировании, именно он используется рядом процедур нашей библиотеки [103].

Для организации процедуры наряду с предложениями, описывающими непосредственный алгоритм решаемой задачи (а в ряде случаев и для обеспечения самого алгоритма), Maple-язык предоставляет ряд важных средств, обеспечивающих функции, управляющие выполнением процедуры. В первую очередь, к ним можно отнести переменные args и nargs, возвращающие соответственно последовательность переданных процедуре фактических аргументов и их количество. Оба эти средства имеют смысл только в рамках процедуры, а по конструкциям вида args{|[n]|[n..m]} можно получать {последовательность фактических аргументов|nй аргумент|

аргументы с nго по mй включительно} соответственно. Тогда как nargs-переменная возвращает количество полученных процедурой фактических аргументов. Назначение данных средств достаточно прозрачно и обусловливает целый ряд их важных приложений при разработке пользовательских процедур. В первую очередь, это относится к обработке получаемых процедурой фактических аргументов. В частности, nargs-переменная необходима с целью обеспечения определенности выполнения вычислений в случае передачи процедуре неопределенного числа аргументов. Следующий простой фрагмент иллюстрирует сказанное:

> SV:= proc() product(args[k], k= 1 .. nargs)/sum(args[k], k= 1 .. nargs) end proc: > 137*SV(42, 47, 62, 67, 89, 96, 350, 39, 44, 59, 64); 22698342960272179200

> GN:= proc() [nargs, [args]] end proc: GN(V, G, S, A, Art, Kr);

[6, [V, G, S, A, Art, Kr]]

> map(whattype, [59, 17/10, ln(x), 9.9, «RANS»]);

[integer, fraction, function, float, string]

>Arg_Type:= proc() map(whattype, [seq(args[k], k= 1 .. nargs)]) end proc:

>Arg_Type(59, 17/10, ln(x), 9.9, «RANS»);

[integer, fraction, function, float, string]

>Arg_Type:= proc() map(whattype, [args[k]$k= 1 .. nargs]) end proc:

>Arg_Type(59, 17/10, ln(x), 9.9, «RANS»);

[integer, fraction, function, float, string]

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

proc() <ТЕЛО> {Ψ(args[1], args[2], …, args[n])|n = nargs} end proc {;|:}

что оказывается весьма удобным механизмом для организации процедур, ориентированных, в первую очередь, на задачи символьных вычислений и обработки [9-14,39].

Дополнительно к переменным args и nargs можно отметить еще одну важную переменную procname, возвращающую имя процедуры ее содержащей. В целом ряде случаев данная переменная оказывается весьма полезной, в частности, при возвращении вызова процедуры невычисленным. С этой целью используется конструкция формата ‘procname(args)’. Многие пакетные процедуры возвращают результат именно в таком виде, если не могут решить задачу. Ряд процедур и нашей библиотеки [103] поступают аналогичным образом. Между тем, переменная может procname использоваться и в других полезных приложениях. Следующий фрагмент иллюстрирует применение указанной переменной как для организации возврата вызова процедуры невычисленным, так и для вывода соответствующего сообщения:

173

AVZ := proc ()

if nargs 6 then

WARNING(«%1(%2)=%3», procname , seqstr(args), `+`(args)/nargs ) else ‘procname (args)’

end if end proc

> AVZ(64, 59, 39, 44, 10, 17);

Warning, AVZ(64, 59, 39, 44, 10, 17)=233/6

> AVZ(64, 59, 39, 44, 10, 17, 6); AVZ(64, 59, 39, 44, 10, 17, 6)

Процедура AVZ при получении не более 6 фактических аргументов выводит соответствующее сообщение, описывающее вызов процедуры и его результат, тогда как в противном случае вызов процедуры возвращается невычисленным. Исходные тексты процедур нашей библиотеки, прилагаемой к книге [103], предоставляют неплохой иллюстративный материал по использованию переменных args, nargs и procname процедуры в различных ситуациях.

174

4.3. Локальные и глобальные переменные Maple

процедуры

Используемые в теле процедуры переменные по области определения делятся на две группы: глобальные (global) и локальные (local). Глобальные переменные определены в рамках всего текущего сеанса работы с ядром пакета и их значения доступны как для использования, так и для модификации в любой момент и в любой Maple-конструкции, где их применение корректно. Для указания переменной глобальной ее идентификатор кодируется в global-секции определения процедуры, обеспечивая процедуре доступ к данной переменной. В этой связи во избежание возможной рассинхронизации вычислений и возникновения ошибочных ситуаций рекомендуется в качестве глобальных использовать в процедурах только те переменные, значения которых ими не модифицируются, а только считываются. В противном случае не исключено возникновение отмеченных ситуаций, включая и непредсказуемые. Следующий пример иллюстрирует некорректность определения в процедуре глобальной х-переменной:

> x:=64: proc(y) global x; x:=0; y^(x+y) end proc(10); evalf(2006/x); 10000000000 Error, numeric exception: division by zero

> x:=64: proc(y) global x; x:=0; y^(x+y) end proc: evalf(2006/x); 31.34375000

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

Если для переменных, используемых в определении процедуры, не определена область их действия (local, global), то Maple-язык классифицирует их следующим образом. Каждая переменная, получающая в теле процедуры определение по (:=)-оператору либо переменная цикла, определяемая функциями {seq, add, mul} полагается локальной (local), остальные полагаются глобальными (global) переменными. При этом, если переменные for-цикла не определены локальными явно, то выводится предупреждающее сообщение вида Warning, `k` is implicitly declared local to procedure `P`, где k и P переменная цикла в процедуре P соответственно. Тогда как для функций sum и product переменные цикла рассматриваются глобальными, не выводя каких-либо сообщений, что предполагает их явное определение в local-сек- ции. Однако вне зависимости от наличия предупреждающих сообщений рекомендуется явно указывать локальные и глобальные переменные, что позволит не только избегать ошибок выполнения, но и более четко воспринимать исходный текст процедуры. Следующий фрагмент иллюстрирует вышесказанное:

> G:= 2: A:= proc(n) V:=64: [args, assign(‘G’, 5), assign(‘V’, 9), assign(cat(H, n), `h`)] end proc:

Warning, `V` is implicitly declared local to procedure `A`

> [A(99), G, V, A(10), whattype(H9), H9]; [[99], 5, 9, [10], symbol, H9]

>k:= 64: H:= proc() product(args[k], k=1 .. nargs)/sum(args[k], k=1 .. nargs) end proc:

>[k, H(42, 47, 62, 67, 96, 89, 10, 17, 4), k];

Error, (in H) invalid subscript selector

> k:= 64: H:= proc() local k; product(args[k], k=1 .. nargs)/sum(args[k], k=1 .. nargs) end proc: > [k, H(42, 47, 62, 67, 96, 89, 10, 17, 4), k]; [64, 109772628480, 64]

> G:=proc() [seq(args[k],k=1..nargs), mul(args[n], n=1..nargs)/add(args[p], p=1..nargs)] end proc:

> k:=64: n:= 95: p:= 99: G(1, 2, 3, 4, 5, 6, 7, 8, 9): [k, n, p];

[64, 95, 99]

> k:=64: P:= () -> [seq(args[k], k=1..nargs)]: P(1, 2, 3), k;

[1, 2, 3], 64

> k:=64: P:= () -> [add(args[k], k=1..nargs)]: P(1, 2, 3), k;

[6], 64

> k:=64: P:= () -> [mul(args[k], k=1..nargs)]: P(1, 2, 3), k;

[6], 64

> k:=64: P:= () -> [sum(args[k], k=1..nargs)]: P(1, 2, 3), k;

Error, (in P) invalid subscript selector

175

> k:=64: P:= () -> [product(args[k], k=1..nargs)]: P(1, 2, 3), k;

Error, (in P) invalid subscript selector

> k:=64: P:=proc() for k to nargs do end do end proc: P(1, 2, 3), k; 64 Warning, `k` is implicitly declared local to procedure `P`

Таким образом, в указанных случаях соответствующие переменные процедуры при ее вычислении неявно декларируются локальными с выводом или без предупреждающих сообщений. С другой стороны, глобальные переменные даже без их явного декларирования в global-сек- ции можно генерировать в рамках процедуры, как это иллюстрирует первый пример предыдущего фрагмента. Делать это позволяет процедура assign. Однако работа с такими глобальными переменными чревата непредсказуемыми последствиями. Таким образом, практика программирования в среде Maple-языка рекомендует следовать следующим двум правилам определения области действия переменных:

(1) глобальными определять переменные лишь используемые в режиме чтения; (2) локальные переменные определять явно в localсекции процедуры.

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

По assign-процедуре в теле процедур можно назначать выражения как локальным (заданным явно), так и глобальным (заданным явно либо неявно) переменным. Однако, здесь имеется одно весьма существенное отличие. Как известно, пакет не допускает динамического генерирования имен в левой части (:=)-оператора присваивания, тогда как на основе assign-процедуры это возможно делать. Это действительно существенная возможность, весьма актуальная в целом ряде задач практического программирования [103]. Между тем, если мы по процедуре assign в теле процедуры будем присваивать выражения локальным переменным и сгенерированным одноименным с ними переменным, то во втором случае присвоения производятся именно глобальным переменным, не затрагивая локальных. Нижеследующий пример весьма наглядно иллюстрирует вышесказанное.

> restart; V42, G47:= 10, 17: proc() local V42, G47; assign(V42=64, G47=59); assign(cat(V, 42)=100, cat(G, 47)=200); [V42, G47] end proc(), [V42, G47]; [64, 59], [100, 200]

Таким образом, данное обстоятельство следует учитывать при работе с динамически генерируемыми переменными в теле процедур.

Следует еще раз отметить, что для предложений присвоения в процедурах в целом ряде случаев использование assign-процедуры является единственно возможным подходом. Однако, при таком подходе в общем случае требуется, чтобы левая часть уравнения x=a в assign(x=a) была неопределенным именем, т.е. для нее должно выполняться соотношение type(x, ‘symbol’) = true. И здесь вполне допустимо использование конструкций следующего общего формата:

assign(op([unassign(‘<Имя>‘), <Имя>]) = <Выражение>)

При этом, для таких объектов как процедуры, модули, таблицы и массивы (включая матрицы и векторы в смысле Maple, а не NAG) кодирование их имен в невычисленном формате необяза

176

тельно, что может существенно облегчать программирование. Следующий весьма простой фрагмент иллюстрирует вышесказанное:

> x:= 64: assign(op([unassign(x), x]) = 59); x; 64

Error, (in unassign) cannot unassign ’64’ (argument must be assignable)

> P:= proc() end proc: M:= module() end module: T:= table([]): A:= array([]): > map(whattype, map(eval, [P, M, T, A])); [procedure, module, table, array]

> seq(assign(op([unassign(k), k])=59), k=[P,M,T,A]); [P,M,T,A], map(type, [P,M,T,A], ‘odd’);

[59, 59, 59, 59], [true, true, true, true]

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

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

Процедура

(1)

global (x = a)

global (x = a)

global (x = a)

(2)

global (x = a)

local (x = b)

global (x = a)

(3)

x true

local (x = b)

x::{name|symbol}

type(x, {name|symbol})

(4)

(x = a) false

Errorситуация

x = a

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

Вслучае (2) определенная локально в теле процедуры х-переменная в рамках процедуры может принимать значения, отличные от ее глобальных значений вне ее, т.е. в процедуре временно подавляется действие одноименной с ней глобальной х-переменной. Однако здесь имеют место и особые случаи (3, 4), не охватываемые стандартным механизмом. Для ряда функций, использующих ранжированные переменные (например, sum, product), возможны две ситуации, если такие переменные не декларировались в процедуре явно. Прежде всего, как отмечалось выше, не выводится предупреждающих сообщений о том, что они предполагаются локальными. Следовательно, они согласно трактовке Maple-языка должны рассматриваться глобальными. Между тем, если на момент вызова процедуры, содержащей такие функции, ранжированная х-переменная была неопределенной (случай 3), то получая значения в процессе выполнения процедуры, после выхода из нее она вновь становится неопределенной, т.е. имеет место глобальное поведение переменной. Если же на момент вызова процедуры х-переменная имела значение, то выполнение процедуры инициирует ошибочную ситуацию, а значение х— переменной остается неизменным (случай 4). Рассмотренные ситуации еще раз говорят в пользу явного определения входящих в процедуру переменных.

Наряду со сказанным, локальные переменные могут использоваться в теле процедур в качестве ведущих переменных с неопределенными для них значениями, например:

> y:= 64: GS:= proc(p) local y, F; F:= y -> sum(y^k, k= 0 .. n); diff(F(y), y$p) end proc: > [y, simplify(GS(2))];

y( n + 1 ) n2 − 2 yn n2 + y(n 1 ) n2 − y(n + 1 ) n + y( n 1 ) n + 2 yn − 2

64,

3

(y − 1)

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

177

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

> P:=proc() local a; global b; x:= 56; assign(‘m’=67); a:= proc(x) m:= 47; assign(‘n’= 89); x end proc; x*a(3) end proc:

Warning, `x` is implicitly declared local to procedure `P` Warning, `m` is implicitly declared local to procedure `a` > n, m:= 100, 100: P(), n, m; 168, 89, 67

> P1:= proc(m::uneval) local a, x; global b; a, x:= 59, 39; b:= 64; assign(‘m’=42) end proc: > m:= 64: P1(m), a, x, b, m; a, x, 64, 42

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

> W:= y^4;

W := y4

(1)

> y:= z^3;

y := z3

> z:= h^2;

z := h2

> h:= 3;

h := 3

> W;

282429536481

> [eval(W, 1), eval(W, 2), eval(W, 3), eval(W, 4)]; [y4, z12, h24, 282429536481]

(2)

> G:= proc() local W, y, z, h; W:= y^4; y:= z^3; z:= h^2; h:= 2; W end proc:

(3)

> [G(), eval(G()), evala(G()), evalf(G())]; [y4, 16777216, y4, y4]

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

Для полного вычисления произвольного В-выражения используется вызов eval(B)-функции. Однако в первом примере фрагмента W-переменная является глобальной, что и определяет ее полное вычисление, если (как это иллюстрирует второй пример) не определено противного. Наконец, третий пример фрагмента иллюстрирует результат вычисления той же рекурсивной цепочки выражений, но уже составляющих тело процедуры и идентификаторы которых определены в ней локальными. Из примера следует, что если не определено противного, то процедура возвращает только первый уровень вычисления W-выражения и для его полного вычисления требуется использование функции eval, как это иллюстрирует последний пример фрагмента. Данное обстоятельство следует всегда иметь в виду, ибо оно не имеет аналогов в традиционных языках программирования и наряду с требованием особого внимания обеспечивает целый ряд весьма интересных возможностей программирования в различных приложениях.

178

4.4. Определяющие параметры и описания Maple

процедур

Прежде всего, представим секцию описания (description), завершающую описательную часть определения процедуры и при ее наличии располагающуюся между секциями {local, global, options} и непосредственно телом процедуры. При отсутствии данных секций description— секция располагается непосредственно за заголовком процедуры и кодируется в следующем формате:

description <Строчная конструкция> {:|;}

Определенная в данной секции строчная конструкция не влияет на выполнение процедуры и используется в качестве комментирующей ее компоненты, т.е. она содержит текстовую информацию, предназначенную, как правило, для документирования процедуры. При этом, в отличие от обычного комментария языка, которое игнорируется при чтении процедуры, описание ассоциируется с процедурой при ее выводе даже тогда, когда ее тело не выводится по причине использования рассматриваемой ниже опции Copyright. Более того, определяемый description-секцией комментарий может быть одного из типов {name, string, symbol}, как это иллюстрирует следующий простой фрагмент:

>REA:= proc() description `Average`; sum(args[k], k= 1 .. nargs)/nargs end proc:

>REA(19.42, 19.47, 19.62, 19, 67, 19, 89, 20.06), eval(REA);

34.07125000, proc () description Average; sum(args[k],k = 1 .. nargs)/nargs end proc

>REA:= proc() option Copyright; description «Average of real arguments»; sum(args[k], k= 1 .. nargs)/nargs end proc:

>eval(REA); proc () description «Average of real arguments» … end proc

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

Рассмотрев секции local, global и description, несколько детальнее остановимся на {options| option}-секции, которая должна кодироваться непосредственно за двумя первыми (или быть первой при их отсутствии) в описательной части определения процедуры. В качестве параметров (опций) данной секции допускаются следующие: builtin, Copyright, trace, arrow, operator, remember и call_external. При этом, перечень опций может зависеть от релиза пакета.

Пакет располагает тремя типами процедур: встроенными непосредственно в ядро пакета, библиотечными и определяемыми самим пользователем. Параметр builtin определяет встроенную функцию пакета и при наличии он должен кодироваться первым в списке параметров option-секции. Данный параметр визуализируется при полном вычислении процедуры посредством eval-функции либо по print-функции, например:

> print(eval), eval(readlib);

proc () option builtin; 169 end proc proc () options builtin, remember; 237 end proc

Каждая встроенная функция идентифицируется уникальным номером (зависящим от номера релиза пакета) и пользователь не имеет прямой возможности определять собственные встроенные функции. В приведенном примере первым выводится результат вызова printфункции, а вторым — evalфункции, из чего следует, что встроенные функции eval и readlib имеют соответственно номера 98 и 152 (Maple 8, тогда как уже для Maple 10 эти номера соответственно будут 117 и 274), а вторая процедура имеет дополнительно и rememberопцию.

179

Для проверки процедур могут быть полезны и наши процедуры ParProc, ParProc1 и Sproc [103], обеспечивающие возврат как основных параметров процедур, модулей и пакетов, так и их местоположение в библиотеках Maple, как это иллюстрирует следующий фрагмент:

> ParProc(MkDir), ParProc(came); map(ParProc, [‘add’, march, goto, iostatus, seq]);

Arguments = (F::{symbol, string })

Arguments = (E::anything

)

locals = (f, h )

,

locals = (cd, r, k, h, z, K, L, Λ, t, d, ω, ω1, u, f, s)

globals = (__Art_Kr_ )

[builtin function, 91, iolib function, 31, builtin function, 193, iolib function, 13, builtin function, 101]

> ParProc(DIRAX);

DIRAX is module with exports [new, replace, extract, empty, size, reverse, insert, delete, sortd, printd, conv]

> ParProc(process); inert_function

process is module with exports [popen, pclose, pipe, fork, exec, wait, block, kill, launch]

> ParProc(Int);

Warning, <Int> is inert version of procedure/function <int>

> ParProc1(ParProc1, ‘h’), h;

Warning, procedure ParProc1 is in library [Proc, User, {«c:/program files/maple 8/lib/userlib»}]

Arguments = (M::{procedure , module })

locals = (a, b, c, d, p, h, t, z, cs, L, R, N, ω, ν) ,

globals = (_62, ParProc, Sproc )

[Proc, User, {«c:/program files/maple 8/lib/userlib» }]

> ParProc1(Sockets, ‘t’), t;

Warning, module Sockets is in library [package, Maple, {«C:\Program Files\Maple 8/lib»}]

[exports = (socketID , Open, Close, Peek, Read, Write, ReadLine , ReadBinary , WriteBinary , Server, Accept, Serve, Address, ParseURL, LookupService , GetHostName , GetLocalHost , GetLocalPort , GetPeerHost , GetPeerPort, GetProcessID , HostInfo , Status , Configure , _pexports )]

[locals = (defun, trampoline , soPath, solib, passign , setup, finalise )]

[options = (package , noimplicit , unload = finalise , load = setup )] [description = («package for connection oriented TCP/IP sockets» )], [package , Maple, {«C:Program FilesMaple 8/lib» }]

>Sproc(MkDir, ‘h’), h; true, [Proc, User, {«c:/program files/maple 9/lib/userlib»}]

>Sproc(`type/package`, ‘h’), h;

true, [Proc, Maple&User, {«C:Program FilesMaple 9/lib», «c:/program files/maple 9/lib/userlib»}]

С описанием данных процедур можно ознакомиться в [103], тогда как сами они находятся в прилагаемой к книге библиотеке. Там же можно получить и их исходные тексты.

Параметр Copyright определяет авторские права процедуры, ограничивая возможности вывода ее определения на печать. В качестве такого параметра пакет рассматривает любую конструкцию option-секции, начинающуюся с Copyrightслова. Все библиотечные Maple-проце- дуры определены с параметром Copyright, требуя для вывода на печать их определений установки опции verboseproc=n (n={2|3}) в interface-процедуре. Типичное содержимое option— секции библиотечных процедур имеет следующий вид:

option `Copyright (c) 1997 Waterloo Maple Inc. All rights reserved.`;

option {system,} `Copyright (c) 1992 by the University of Waterloo. All rights reserved.`;

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

interface(verboseproc=3): {print|eval}(<Idпроцедуры>);

как это иллюстрирует следующий достаточно простой пример:

180

Соседние файлы в папке Books

  • #
  • #

    18.03.201519.23 Mб35Дьяконов_maple_9.5-10.djvu

I am given the following dynamical system:

$x’= -(x^3/(1+x^2))+ lambda x^2+mu$

I need to find all bifurcation points when $lambda$ and $mu$ vary on the reals, and study their type. (Note: I’m using Maple software to solve this). Please note that this is my very first attempt at solving such an exercise, I have never dealt with dynamical systems before. Any kind of help would be much appreciated.

First of all, I wanted to find all non-hyperbolic equilibrium points of the system, that is, if $f = -(x^3/(1+x^2))+ lambda x^2+mu $,

$begin{cases} f(x,lambda,mu)=0 \ partial f/ partial x f (x,lambda, mu) = 0 end{cases}$

For some reason, Maple (a software I am not too familiar with, but I am required to use that) does not give me explicit solutions for this system. It actually just doesn’t compute anything.

So, I have tried a sightly different approach, as done in this example by Hale-Kocak. By solving the second equation with respect to $lambda$ (parameter $mu$ vanishes after derivating), I get

$lambda = (1/2)x(x^2+3)/(x^2+1)^2$

And by substituting in the first one, solving with respect to $mu$,

$mu = (1/2)x^3(x^2-1)/(x^2+1)^2$

.. and at this point I’m stuck again. I should get the relation between $lambda$ and $mu$ as they have done with parameters $c$ and $d$ in their example, but I can’t seem to find a way to do it.

Any hint is welcome. I’m in serious need of ideas on how to start solving this.

Понравилась статья? Поделить с друзьями:
  • Error invalid subscript selector maple
  • Error invalid storage class for function
  • Error invalid smb conf
  • Error invalid server check your port forwarding settings connection to lobby failed attempt number
  • Error invalid request squid