->, -->, proc, name, option, local, begin, end_proc, procname

Задайте процедуру

Блокноты MuPAD® будут демонтированы в будущем релизе. Используйте live скрипты MATLAB® вместо этого.

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

Синтаксис

( x1, x2, … ) -> body
proc(
     x1 <= default1> <: type1>,
     x2 <= default2> <: type2>,
     ...
    ) <: returntype>
  <name pname;>
  <option option1, option2, …>
  <local local1, local2, …>
  <save global1, global2, …>
begin
   body
end_proc

( x1, x2, … ) --> body
_procdef(, …)

Описание

proc - end_proc задает процедуру.

Процедуры f := proc(x1, x2, ...) ... end_proc может быть назван как системная функция в форме f(x1, x2, ...). Возвращаемое значение этого вызова является значением последней команды, выполняемой в теле процедуры (или значение, возвращенное телом через функциональный return).

Описание процедуры (x1, x2, ...) -> body эквивалентно proc(x1, x2, ...) begin body end_proc. Это полезно для определения простых процедур, для которых не нужны локальные переменные. Например, f := x -> x^2 задает математическую функцию. Если процедура использует больше чем один параметр, используйте скобки в качестве в f := (x, y) -> x^2 + y^2. См. пример 1.

Описание процедуры (x1, x2, ...) --> body эквивалентно fp::unapply(body, x1, x2, ...). Различием от других определений является тот body оценен прежде, чем задать процедуру. См. Пример 2.

Примечание

Оценка body не должен содержать ссылки на параметры или локальные переменные внешней процедуры.

Процедура MuPAD® может иметь произвольное число параметров. Для каждого параметра может быть задано значение по умолчанию. Это значение используется, если никакое фактическое значение не передается, когда процедура называется. Например,

f := proc(x = 42) begin body end_proc

задает значение по умолчанию параметра x быть 42. Вызов f() эквивалентно f(42). См. пример 3.

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

f := proc(x : DOM_INT) begin body end_proc

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

Также автоматическая проверка типа возвращаемое значение может быть реализована, задав returntype. См. пример 4.

С ключевым словом name, имя может быть задано для процедуры, например,

f := proc(...) name myName; begin body end_proc.

Существует специальная переменная procname сопоставленный с процедурой, которая хранит ее имя. Когда тело отвечает на символьный звонок procname(args()), подлинным именем подставляются. Это - имя, заданное дополнительным name запись. Если никакой name запись задана, первый идентификатор, которому была присвоена процедура, используется в качестве имени, т.е. f в этом случае. См. Пример 5.

С ключевым словом option, специальные функции могут быть заданы для процедуры:

  • escape

    Должен использоваться, если процедура создает и возвращает новую процедуру который доступы локальные значения процедуры включения. См. Пример 6. Эта опция должна только использоваться при необходимости. Также обратитесь к Pref::warnDeadProcEnv.

  • hold

    Препятствует тому, чтобы процедура оценила фактические параметры, которыми она вызвана. Смотрите Пример 7.

  • noDebug

    Препятствует тому, чтобы отладчик исходного кода MuPAD ввел эту процедуру. Также обратитесь к Pref::ignoreNoDebug. См. пример 8.

  • noFlatten

    Предотвращает выравнивание последовательностей, переданных в качестве аргументов процедуры. Смотрите Пример 9.

  • remember

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

    Это может убыстриться, например, рекурсивные процедуры решительно. См. Пример 10. Однако помнить таблица может стать большой и использовать большую память. Кроме того, полноценность этой функции очень ограничена в свете свойств — идентификация “тех же входных параметров” не зависит от предположений на идентификаторах или глобальных переменных, таких как DIGITS и ORDER, таким образом, возвращенный результат не может быть совместим с новыми предположениями. Использование prog::remember вместо этой опции настоятельно рекомендован для любой функции, принимающей символьный вход.

  • noExpose

    Дает MuPAD команду скрывать тело процедуры от пользователя. Обратите внимание на то, что это предотвращает отладку процедуры, также. См. Пример 15.

С ключевым словом local, локальные переменные процедуры заданы, например,

f := proc(...) local x, y; begin body end_proc.

См. пример 11.

Локальные переменные не могут использоваться в качестве “символьных переменных” (идентификаторы). Они должны быть присвоенными значениями, прежде чем они смогут использоваться в расчетах.

Обратите внимание на то, что имена глобальных переменных MuPAD такой DIGITS, READPATH и т.д. не должен использоваться в качестве локальных переменных. Также отошлите к ключевому слову save.

С ключевым словом save, локальный контекст для глобальных переменных MuPAD создается, например,

f := proc(...) save DIGITS; begin DIGITS := newValue; ... end_proc.

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

Можно задать процедуры, которые принимают переменное количество аргументов. Например, можно объявить процедуру без любых формальных параметров. В теле к фактическим параметрам, которыми вызвана процедура, можно получить доступ через функциональный args. См. пример 13.

Вызов имени процедуры f, Скажем, обычно не распечатывает исходный код тела на экран. Используйте expose(f) видеть тело. См. Пример 14.

Переменная окружения MAXDEPTH ограничивает “глубину вложения” рекурсивных вызовов процедуры. Значением по умолчанию является MAXDEPTH = 500. См. пример 10.

Если процедура является область паз, специальная переменная dom содержит имя области, которой принадлежит паз. Если процедура не является доменным пазом, значением dom NIL.

Вместо end_proc, также ключевое слово end может использоваться.

Обязательное объявление proc - end_proc внутренне результаты в вызове ядра функционируют _procdef. Нет никакой потребности вызвать _procdef непосредственно.

При оценке процедуры MuPAD анализирует целую процедуру сначала, и только затем выполняет ее. Если вы хотите ввести новый синтаксис (например, задайте новый operator), сделайте это вне процедуры. Смотрите Пример 16.

Примеры

Пример 1

Простые процедуры могут быть сгенерированы с “оператором стрелы” ->:

f := x -> x^2 + 2*x + 1:
f(x), f(y), f(a + b), f(1.5)

f := n -> isprime(n) and isprime(n + 2):
f(i) $ i = 11..18

Следующая команда сопоставляет “анонимную” процедуру с элементами списка:

map([1, 2, 3, 4, 5, 6], x -> x^2)

delete f:

Пример 2

Объявление процедур с “оператором стрелы” является мощным инструментом. В некоторых ситуациях, однако, это приводит к потенциально неожиданным результатам:

f := x -> sin(x^2)

g := x -> f'(x)

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

g := x --> f'(x)

Конечно, в этом примере, существует еще более короткий путь:

g := f'

Пример 3

Объявление значений по умолчанию продемонстрировано. Следующая процедура использует значения по умолчанию, если вызов процедуры не обеспечивает все значения параметров:

f := proc(x, y = 1, z = 2) begin [x, y, z] end_proc:
f(x, y, z), f(x, y), f(x)

Никакое значение по умолчанию не было объявлено для первого аргумента. Предупреждение выдано, если этот аргумент отсутствует:

f()
Warning: Uninitialized variable 'x' is used.
  Evaluating: f

delete f:

Пример 4

Автоматическая проверка типа аргументов процедуры и возвращаемых значений продемонстрирована. Следующая процедура принимает только положительные целые числа как аргумент:

f := proc(n : Type::PosInt) begin n! end_proc:

Ошибка повышена, если неподходящий параметр передается:

f(-1)
Error: Invalid object '-1'. Type of argument number 1 must be 'Type::PosInt'.
  Evaluating: f
Error: Wrong type of 1. argument (type 'Type::PosInt'
expected,        got argument '-1');   Evaluating: f 

В следующей процедуре вызывается автоматическая проверка типа возвращаемого значения:

f := proc(n : Type::PosInt) : Type::Integer
begin 
  n/2 
end_proc:

Ошибка повышена, если возвращаемое значение не является целым числом:

f(3)
Error: Invalid return value '3/2'. It must be of type 'Type::Integer'.
  Evaluating: f
Error: Wrong type of return value (type 'Type::Integer'
expected,        value is '3/2');   Evaluating: f 
delete f:

Пример 5

name запись процедур продемонстрирована. Процедура отвечает на символьный звонок к себе при помощи переменной procname это содержит текущее имя процедуры:

f := proc(x)
begin
  if testtype(x,Type::Numeric) 
    then return(float(1/x))
    else return(procname(args()))
  end_if
end_proc:
f(x), f(x + 1), f(3), f(2*I)

Также сообщения об ошибке используют это имя:

f(0)
Error: Division by zero. [_invert]
  Evaluating: f

Если процедура имеет запись имени, эта запись используется:

f := proc(x)
name myName;
begin
  if testtype(x,Type::Numeric) 
    then return(float(1/x))
    else return(procname(args()))
  end_if
end_proc:
f(x), f(x + 1), f(3), f(2*I)

f(0)
Error: Division by zero. [_invert]
  Evaluating: myName
delete f:

Пример 6

Опция escape продемонстрирован. Эта опция должна использоваться, если процедура возвращает другую процедуру, которая ссылается на формальный параметр или локальную переменную генерирующейся процедуры:

f := proc(n) 
begin 
  proc(x) begin x^n end_proc
end_proc:

Без опции escape, формальный параметр n 'off' листы его осциллограф: g := f(3) ссылки n внутренне. Когда g называется, это не может оценить n к значению 3 тот n имел в осциллографе функционального f:

g := f(3): g(x)
Warning: Uninitialized variable 'unknown' is used.
  Evaluating: g
Error: Invalid operand. [_power]
  Evaluating: g

Опция escape сообщает процедуре f иметь дело с переменными, выходящими из локального осциллографа. Теперь процедура g := f(3) ссылается на значение 3 вместо формального параметра n 'off', и g может быть выполнен правильно:

f := proc(n) 
option escape;
begin  
  proc(x) begin x^n end_proc 
end_proc:
g := f(3): g(x), g(y), g(10)

delete f, g:

Пример 7

Опция hold продемонстрирован. С hold, процедура видит фактический параметр в форме, которая использовалась в вызове процедуры. Без hold, функция только видит значение параметра:

f := proc(x) option hold; begin x end_proc:
g := proc(x) begin x end_proc:
x := PI/2: 
f(sin(x) + 2) = g(sin(x) + 2), f(1/2 + 1/3) = g(1/2 + 1/3)

Процедуры с помощью option hold может оценить аргументы с функциональным context:

f := proc(x) option hold; begin x = context(x) end_proc:
f(sin(x) + 2), f(1/2 + 1/3)

delete f, g, x:

Пример 8

Опция noDebug продемонстрирован. debug команда запускает отладчик, который продвигается в процедуре f. После ввода команды отладчика c (продолжите), отладчик продолжает оценку:

f := proc(x) begin x end_proc: debug(f(42))
Activating debugger...   #0 in f($1=42) at
/tmp/debug0.556:4 mdx> c Execution completed.                 
               42 

С опцией noDebug, отладчик не продвигается в процедуру:

f := proc(x) option noDebug; begin x end_proc: debug(f(42))
Execution completed.                      
          42 
delete f:

Пример 9

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

f := proc(x, y) begin table(x = y) end_proc:

Параметры x, y из процедуры f сформируйте последовательность. Если вы вызываете эту процедуру для последовательности (a, b) и переменная c, MuPAD сглаживает вложенную последовательность ((a, b), c) в (a, b, c). Процедура f принимает только два аргумента. Таким образом это использует a и b, и игнорирует c:

f((a, b), c)

Когда вы используете noFlatten опция, MuPAD не сглаживает аргументы процедуры:

g := proc(x, y) option noFlatten; begin table(x = y) end_proc:
g((a, b), c)

Для дальнейших расчетов удалите f и g:

delete f, g:

Пример 10

Опция remember продемонстрирован. print команда в следующей процедуре указывает, выполняется ли тело процедуры:

f:= proc(n : Type::PosInt)
option remember;
begin
   print("computing ".expr2text(n)."!");
   n!
end_proc:
f(5), f(10)

При вызове процедуры снова, все значения, которые были вычислены прежде, приняты от внутреннего, “помнят таблицу”, не выполняя тело процедуры снова:

f(5)*f(10) + f(15)

option remember используется в следующей процедуре, которая вычисляет Числа Фибоначчи F (0) = 0, F (1) = 1, F (n) = F (n - 1) + F (n - 2) рекурсивно:

f := proc(n : Type::NonNegInt)
option remember;
begin
   if n = 0 or n = 1 then return(n) end_if;
   f(n - 1) + f(n - 2)
end_proc:
f(123)

Из-за рекурсивной природы f, аргументы ограничиваются максимальной рекурсивной глубиной (см. MAXDEPTH):

f(1000)
Error: Recursive definition: Reached maximal depth for nested procedure calls.
  Evaluating: f

Без optionremember, рекурсия является довольно медленной:

f := proc(n : Type::NonNegInt)
begin
   if n = 0 or n = 1 then return(n) end_if;
   f(n - 1) + f(n - 2)
end_proc:
f(28)

delete f:

Пример 11

Мы демонстрируем использование локальных переменных:

f := proc(a)
local x, y;
begin
  x := a^2; 
  y := a^3;
  print("x, y" = (x, y));
  x + y
end_proc:

Локальные переменные x и y не совпадайте с глобальными переменными xY вне процедуры. Вызов f не изменяет глобальные значения:

x := 0: y := 0: f(123), x, y

delete f, x, y:

Пример 12

save объявление продемонстрировано. Следующая процедура изменяет переменную окружения DIGITS внутренне. Из-за save DIGITS, исходное значение DIGITS восстанавливается после возвращаются из процедуры:

myfloat := proc(x, digits)
save DIGITS;
begin
  DIGITS := digits;
  float(x);
end_proc:

Текущее значение DIGITS :

DIGITS

С настройкой по умолчанию DIGITS = 10, следующее преобразование плавающее страдает от числовой отмены. Из-за более высокой внутренней точности, myfloat приводит к более точному результату:

x := 10^20*(PI - 21053343141/6701487259): 
float(x), myfloat(x, 20)

Значение DIGITS не был изменен вызовом myfloat:

DIGITS

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

f := proc(n)
save x;
begin
  delete x;
  int(x^n*exp(-x), x = 0..1)
end_proc:
x := 3: f(1), f(2), f(3)

Из-за save x, ранее присвоенное значение x восстанавливается после интегрирования:

x

delete myfloat, x, f:

Пример 13

Следующая процедура принимает произвольное число аргументов. Это получает доступ к фактическим параметрам через args, помещает их в список, инвертирует список через revert, и возвращает его аргументы в обратном порядке:

f := proc()
local arguments;
begin
   arguments := [args()];
   op(revert(arguments))
end_proc:
f(a, b, c)

f(1, 2, 3, 4, 5, 6, 7)

delete f:

Пример 14

Используйте expose видеть исходный код процедуры:

f := proc(x = 0, n : DOM_INT)
begin 
  sourceCode;
end_proc

expose(f)
proc(x = 0, n : DOM_INT)
  name f;
begin
  sourceCode
end_proc
delete f:

Пример 15

Опция noExpose препятствует тому, чтобы пользователи читали определение процедуры:

f := proc(a)
  option noExpose;
begin
  print(sin(a));
  if is(a>1)=TRUE then
    cos(a)
  else
    cos(a + 2)
  end_if
end_proc

f(x), f(0), f(3)

expose(f)
proc(a)
  name f;
  option noDebug, noExpose;
begin
  /* Hidden */
end_proc

Как вы видите, устанавливая опцию noExpose неявно устанавливает опцию noDebug, также.

Для получения дополнительной информации о надлежащем использовании этой опции обратитесь к документации write.

Пример 16

Когда вы оцениваете процедуру, MuPAD анализирует целую процедуру, и только затем выполняет ее. Таким образом вы не можете задать и использовать новый оператор в процедуре. Например, когда MuPAD анализирует эту процедуру, он не распознает новый оператор <<. Причина состоит в том, что процедура еще не выполняется, и поэтому, новый оператор не задан:

f := proc(A, B)
begin
  bitshiftleft := (a, b) -> a * 2^b:
  operator("<<", bitshiftleft, Binary, 950):

  C := A<<B;

end_proc:
Error: Invalid input. Expected 'expression'. [line 6, col 10]

Задайте оператор << на интерактивном уровне:

bitshiftleft := (a, b) -> a * 2^b:
operator("<<", bitshiftleft, Binary, 950):

Теперь можно использовать << в процедурах на интерактивном уровне:

f := proc(A, B)
begin 
  C := A<<B;
end_proc:
f(2, 1)

m<<n

Параметры

x1, x2, …

Формальные параметры процедуры: идентификаторы

default1, default2, …

Значения по умолчанию для параметров: произвольные объекты MuPAD

type1, type2, …

Допустимые типы для параметров: текстовые объекты, как принято функциональным testtype

returntype

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

pname

Имя процедуры: выражение

option1, option2, …

Доступные параметры: escapeсодержание, noDebug, noExpose, noFlatten, remember

local1, local2, …

Локальные переменные: идентификаторы

global1, global2, …

Глобальные переменные: идентификаторы

body

Тело процедуры: произвольная последовательность операторов

Возвращаемые значения

Процедура типа DOM_PROC.

Смотрите также

Функции MuPAD

Для просмотра документации необходимо авторизоваться на сайте