hold
Задержите оценку
Блокноты MuPAD® будут демонтированы в будущем релизе. Используйте live скрипты MATLAB® вместо этого.
Live скрипты MATLAB поддерживают большую часть функциональности MuPAD, хотя существуют некоторые различия. Для получения дополнительной информации смотрите, Преобразовывают Notebook MuPAD в Live скрипты MATLAB.
hold(object
)
hold(object)
предотвращает оценку object
.
Когда объект MuPAD® вводится в интерактивном режиме, затем система оценивает его и возвращает оцененный результат. Когда объект MuPAD передается в качестве аргумента процедуре, затем процедура обычно оценивает аргумент прежде, чем обработать его. Оценка означает, что идентификаторы заменяются их значениями, и вызовы функции выполняются. hold
предназначается, чтобы предотвратить такую оценку, когда это - нежелательный.
Типовое приложение hold
- когда функция, которая может только обработать числовые аргументы, но не символические единицы, должна использоваться в качестве выражения. Смотрите Пример 6.
Другая возможная причина для использования hold
является эффективностью. Например, если вызов функции f(x, y)
с символьными аргументами передается в качестве аргумента другой функции, но, как известно, возвращает себя символически, то возможно дорогостоящей оценки “внутреннего” вызова функции можно избежать путем передачи выражения hold(f) (x, y)
в качестве аргумента к “внешней” функции вместо этого. Затем аргументы x, y
оценены, но вызов f
не выполняется. Смотрите Пример в качестве примера 1 и Пример 7.
Начиная с использования hold
может привести к странным эффектам, рекомендуется использовать его только при необходимости.
hold
только задерживает оценку объекта, но не может полностью предотвратить ее на длительном периоде; смотрите Пример 5.
Можно использовать freeze
, чтобы полностью предотвратить оценку процедуры или функциональной среды.
Процедура MuPAD может быть объявлена с опцией, содержат. Это имеет эффект, что аргументы передаются процедуре unevaluatedly. Смотрите страницу справки proc
для деталей.
eval
функций или level
могут использоваться, чтобы обеспечить последующую оценку неоцененного объекта (см. Пример в качестве примера 2). В процедурах с option hold
используйте context
вместо этого.
В следующем двум примерам оценка выражения MuPAD предотвращена с помощью hold
:
x := 2: hold(3*0 - 1 + 2^2 + x)
hold(error("not really an error"))
Без hold
результаты были бы следующие:
x := 2: 3*0 - 1 + 2^2 + x
error("not really an error")
Error: not really an error
Следующая команда предотвращает оценку операции _plus
, но не оценку операндов:
hold(_plus)(3*0, -1, 2^2, x)
Обратите внимание на то, что в предыдущем примере, аргументы вызова функции оценены, потому что hold
применяется только к функциональному _plus
. В следующем примере аргумент вызова функции оценен, несмотря на то то, что f
имеет опцию, содержите:
f := proc(a) option hold; begin return(a + 1) end_proc: x := 2: hold(f)(x)
Это происходит по следующей причине. Когда f
оценен, опция, hold
предотвращает оценку аргумента x
f
(см. следующий пример). Однако, если оценка f
предотвращена hold
, то опция, hold
не имеет никакого эффекта и MuPAD, оценивает операнды, но не вызов функции.
Следующий пример показывает ожидаемое поведение:
f(x), hold(f(x))
Функциональный eval
отменяет эффект hold
. Обратите внимание на то, что это приводит к очень отличающимся результатам, в зависимости от того, как это применяется:
eval(f(x)), eval(hold(f)(x)), eval(hold(f(x))), eval(hold(f))(x)
Несколько вызовов hold
могут быть вложены, чтобы предотвратить последующие оценки:
x := 2: hold(x), hold(hold(x))
Результатом hold ( hold(x) )
является неоцененный операнд внешнего вызова hold
, то есть, hold(x)
. Применение eval
оценивает результат hold(x)
и приводит к неоцененному идентификатору x
:
eval(%)
Другое приложение eval
приводит к значению x
:
eval(%)
delete x, f:
Следующая команда предотвращает оценку операции _plus
, заменяет его операцией _mult
, и затем оценивает результат:
eval(subsop(hold(_plus)(2, 3), 0 = _mult))
Функциональный domtype
оценивает свои аргументы:
x := 0: domtype(x), domtype(sin), domtype(x + 2)
Используя hold
, может быть определен доменный тип неоцененных объектов: x
и sin
являются идентификаторами, и x + 2
является выражением:
domtype(hold(x)), domtype(hold(sin)), domtype(hold(x + 2))
hold
предотвращает только одну оценку объекта, но это не предотвращает оценку в более позднее время. Таким образом с помощью hold
, чтобы получить символ без значения обычно является не хорошей идеей:
x := 2: y := hold(x); y
В этом примере удаляя значение идентификатора x
делает его символом и использованием, hold
не необходим:
delete x: y := x; y
Однако лучший способ получить новый символ без значения состоит в том, чтобы использовать genident
:
y := genident("z"); y
delete y:
Рассмотрите кусочный заданный функциональный f (x), который является тождественно нулевым на отрицательной вещественной оси и равным на положительной вещественной оси:
f := x -> if x < 0 then 0 else exp(-x) end_if:
Эта функция не может быть вызвана с символьным аргументом, потому что условие x <0 не может быть решено:
f(x)
Error: Unable to evaluate to Boolean. [_less] Evaluating: f
Мы хотим интегрировать f
численно. Однако числовой интегратор ожидает функцию как выражение:
numeric::int(f(x), x = -2..2)
Error: Unable to evaluate to Boolean. [_less] Evaluating: f
Решение состоит в том, чтобы подавить преждевременную оценку f
при передаче функции с символьным аргументом. В числовом интеграторе численными значениями заменяют x, прежде чем функция будет вызвана и оценена:
numeric::int(hold(f)(x), x = -2..2)
Функциональный int
не может вычислить закрытую форму следующего интеграла и отвечает на символьный звонок int
:
int(sqrt(x)*sqrt(sqrt(x) + 1), x)
После изменения variablessqrt(x)=t
может быть вычислена закрытая форма:
t := time(): f := intlib::changevar(int(sqrt(x)*sqrt(sqrt(x) + 1), x), sqrt(x) = y); time() - t; eval(f)
Измерение вычислительных времен с time
показывает: Наиболее часто в вызове intlib::changevar
потрачен в переоценке аргумента. Это может быть предотвращено при помощи hold
:
t := time(): f := intlib::changevar(hold(int)(sqrt(x)*sqrt(sqrt(x) + 1), x), sqrt(x) = y); time() - t;
|
Любой объект MuPAD |
Объект Unevaluated.