Операции с дескриптором функции в Matlab

Не могли бы вы помочь мне со следующей проблемой: у меня есть следующий дескриптор функции:

r1 = @(lambda) b + lambda*(r - b); % r and b are vectors of return data

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

lambda0 = 0.3;
for a = 2:10    %power coefficient
S1(a) = fzero(mean((r - b)*r1.^(1/(a - 1))),lambda0);
end

Любое предложение о том, как решить эту проблему, высоко ценится! Заранее спасибо.


person Astrid    schedule 18.03.2016    source источник


Ответы (1)


fzero принимает дескриптор функции в качестве первого ввода. Как у вас сейчас есть, вы пытаетесь передать оператор в качестве первого ввода. Этот оператор даже не может быть правильно оценен, потому что вы пытаетесь выполнить числовые операции с дескриптором функции (подробнее об этом чуть позже).

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

S1(a) = fzero(@(lambda)mean((r - b)*r1(lambda).^(1/(a - 1))),lambda0);

Дальнейшее объяснение

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

Так, например, если бы у нас был дескриптор функции:

func = @(x)2*x;

Если мы оценим это, вызвав его с входным значением для x

func(2)

    4

Это работает так, как мы и ожидали. Если теперь нам действительно нужно значение (2*x)^2, мы могли бы попытаться написать его так, как вы написали свое утверждение в своем вопросе.

func2 = func^2;

Мы получим ошибку!

Неопределенный оператор '^' для входных аргументов типа 'function_handle'.

Это не работает, потому что MATLAB пытается применить операцию ^ к самому дескриптору функции, а не к значению оцениваемого дескриптора функции.

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

func2 = @(x)func(x)^2;
func2(2)

    16

Полный круг

Итак, если мы вернемся к вашему вопросу, вы определили свою анонимную функцию r1 следующим образом.

r1 = @(lambda) b + lambda*(r - b); % r and b are vectors of return data

Все это выглядит великолепно. У вас есть один входной аргумент, и вы ссылаетесь на r и b из родительской рабочей области.

Теперь, когда вы вызываете fzero, вы пытаетесь выполнить операции с этим дескриптором функции в надежде создать новый дескриптор функции.

mean((r - b)*r1.^(1/(a - 1)))

Как мы только что показали, это приведет к очень похожей ошибке.

Неопределенный оператор .^ для входных аргументов типа 'function_handle'

Поэтому нам нужно обернуть это в новую функцию.

newfunc = @(lambda)mean((r - b)*r1(lambda).^(1 / (a - 1)));

Теперь мы можем безопасно передать это fzero.

result = fzero(newfunc, lambda0);
person Suever    schedule 18.03.2016
comment
Спасибо за дополнительное объяснение, это действительно помогло мне понять механизм проблемы. - person Astrid; 18.03.2016
comment
У меня есть дополнительный вопрос: можно ли ограничить значения лямбда-выражений в [0,1] с помощью fzero? - person Astrid; 18.03.2016
comment
@Astrid Вы бы передали границы [lower, upper] для лямбда в качестве второго ввода, а не указывали lambda0. Документация - person Suever; 18.03.2016
comment
Спасибо за быстрый ответ. Если я заменю lambda0 на [0,1], я получу следующую ошибку: Ошибка при использовании fzero (строка 273) Значения функции в конечных точках интервала должны отличаться по знаку. - person Astrid; 18.03.2016
comment
@Астрид Ага. Проверьте ссылку на документацию выше, и она объясняет, почему это так. - person Suever; 18.03.2016
comment
Я также пробовал с [-0.00001, 1], но он возвращает мне тот же результат, что и при установке лямбда0, поэтому на самом деле это не ограничивает лямбда в [0,1]. - person Astrid; 18.03.2016
comment
@Astrid, возможно, откройте новый вопрос, чтобы другие могли помочь вам больше - person Suever; 18.03.2016
comment
Еще раз спасибо за помощь! - person Astrid; 18.03.2016