Могу ли я повторно использовать результат выражения внутри анонимной функции? - PullRequest
2 голосов
/ 04 апреля 2019

У меня есть анонимная функция, такая как @(x) sqrt(x) + 1./sqrt(x) - 3, которую я хочу передать другой функции, например,

fsolve(@(x) sqrt(x) + 1./sqrt(x) - 3, 3)

Представьте себе, аргумент sqrt немного сложнее и, следовательно, sqrt(...) вызов сложен для вычисления - возможно ли создать анонимную функцию, которая сначала вычисляет (в этом простом примере) sqrt(x), а затем использует результат res для вычисления res + 1/res - 3?

Или это можно запрограммировать только с помощью обычной функции?

Ответы [ 2 ]

6 голосов
/ 04 апреля 2019

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

% Original function
orig = @(x) sqrt(x) + 1./sqrt(x) - 3;

% Complicated inner function
inner = @(x) sqrt(x);

% Actual function
func = @(y) y + 1./y - 3;

% Function wrapper
wrapper = @(z) func(inner(z));

% Some small tests
X = 1:10;
orig(X)
wrapper(X)

ans =
  -1.000000  -0.878680  -0.690599  -0.500000  -0.316718  -0.142262   0.023716   0.181981   0.333333   0.478505

ans =
  -1.000000  -0.878680  -0.690599  -0.500000  -0.316718  -0.142262   0.023716   0.181981   0.333333   0.478505

Сложная внутренняя функция оценивается только один раз - по крайней мере, с моей точки зрения.

2 голосов
/ 04 апреля 2019

Да, вы можете сделать это (хотя действительно ли это правильное решение вашей реальной проблемы может быть предметом споров).

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

MATLAB обрабатывает определение анонимной функции внутри определения анонимной функции точно так, как вы ожидаете, что синтаксис позволит вам.Бит «оценить немедленно» можно сделать с помощью feval:

@(x) feval(@(res) res + 1./res - 3, sqrt(x))
...