I am trying to code a very basic Mean Likelihood Estimator function that relies on the Optimization Toolbox's fminsearch()
function. I try to pass a function handle as an input and optimize the sum of the neg. of the function's log. My code is:
function [ params, max ] = routine( fun )
%UNTITLED3 Summary of this function goes here
% Detailed explanation goes here
[filename,path] = uigetfile('*.'); #To grab the csv file location
name = strcat(path,filename);
data = csvread(name);
lh = @(x) sum(-log( fun(x) )); <-------- ERROR LINE
options = optimset('Display', 'off', 'MaxIter', 100000, 'TolX', 10^-20, 'TolFun', 10^-20);
[theta, max1] = fminsearch(lh, [0,1], options);
params = theta
max = max1
end
The line in the middle is giving me this error:
Undefined function or variable 'data'.
Error in @(x)(1/(sqrt(2*pi)*x(2)))*exp((-(data-x(1)).^2)/(2*x(2)^2))
Error in @(x)sum(-log(fun(x)),data)
Error in fminsearch (line 200)
fv(:,1) = funfcn(x,varargin{:});
Now, outside this code, this works perfectly fine, infuriatingly enough.
pan = @(x)sum(-log((1/(sqrt(2*pi)*x(2)))*exp((-(data-x(1)).^2)/(2*x(2)^2))));
options = optimset('Display', 'off', 'MaxIter', 100000, 'TolX', 10^-20, 'TolFun', 10^-20);
[theta, max1] = fminsearch(pan, [0,1], options);
For some reason, transforming the equation the way I do in the middle makes the data
var. invisible. How should I correctly apply the transformation to my equation such that this code works?
Take a look at the documentation on anonymous functions. Here's the relevant part
Variables in the Expression
Function handles can store not only an expression, but also variables that the expression requires for evaluation.
For example, create a function handle to an anonymous function that requires coefficients
a
,b
, andc
.a = 1.3; b = .2; c = 30; parabola = @(x) a*x.^2 + b*x + c;
Because
a
,b
, andc
are available at the time you createparabola
, the function handle includes those values. The values persist within the function handle even if you clear the variables:clear abc x = 1; y = parabola(x)
y = 31.5000
To supply different values for the coefficients, you must create a new function handle
In your case the value of data
that you read in won't be available to fun
since the function handle was defined before data
. Instead we can just make data
a parameter of fun
then we avoid the problem all together.
calling code
myfun = @(x,data) (1/(sqrt(2*pi)*x(2)))*exp((-(data-x(1)).^2)/(2*x(2)^2));
[params,max] = routine(myfun);
routine.m (the bit which needs to be changed)
function [ params, max ] = routine( fun )
...
lh = @(x) sum(-log( fun(x,data) ));
...
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.