Using MLE function to estimate the parameters of a custom distribution - matlab

I am trying to use mle() function in MATLAB to estimate the parameters of a 6-parameter custom distribution.
The PDF of the custom distribution is
and the CDF is
where Γ(x,y) and Γ(x) are the upper incomplete gamma function and the gamma function, respectively. α, θ, β, a, b, and c are the parameters of the custom distribution. K is given by
Given a data vector 'data', I want to estimate the parameters α, θ, β, a, b, and c.
So, far I have come up with this code:
data = rand(20000,1); % Since I cannot upload the acutal data, we may use this
t = 0:0.0001:0.5;
fun = #(w,a,b,c) w^(a-1)*(1-w)^(b-1)*exp^(-c*w);
% to estimate the parameters
custpdf = #(data,myalpha,mybeta,mytheta,a,b,c)...
((integral(#(t)fun(t,a,b,c),0,1)^-1)*...
mybeta*...
igamma(myalpha,((mytheta/t)^mybeta)^(a-1))*...
(mytheta/t)^(myalpha*mybeta+1)*...
exp(-(mytheta/t)^mybeta-(c*(igamma(myalpha,(mytheta/t)^mybeta)/gamma(myalpha)))))...
/...
(mytheta*...
gamma(myalpha)^(a+b-1)*...
(gamma(myalpha)-igamma(myalpha,(mytheta/t)^mybeta))^(1-b));
custcdf = #(data,myalpha,mybeta,mytheta,a,b,c)...
(integral(#(t)fun(t,a,b,c),0,1)^-1)*...
integral(#(t)fun(t,a,b,c),0,igamma(myalpha,(mytheta/t)^mybeta)^mybeta/gamma(myalpha));
phat = mle(data,'pdf',custpdf,'cdf',custcdf,'start',0.0);
But I get the following error:
Error using mlecustom (line 166)
Error evaluating the user-supplied pdf function
'#(data,myalpha,mybeta,mytheta,a,b,c)((integral(#(t)fun(t,a,b,c),0,1)^-1)*mybeta*igamma(myalpha,((mytheta/t)^mybeta)^(a-1))*(mytheta/t)^(myalpha*mybeta+1)*exp(-(mytheta/t)^mybeta-(c*(igamma(myalpha,(mytheta/t)^mybeta)/gamma(myalpha)))))/(mytheta*gamma(myalpha)^(a+b-1)*(gamma(myalpha)-igamma(myalpha,(mytheta/t)^mybeta))^(1-b))'.
Error in mle (line 245)
phat = mlecustom(data,varargin{:});
Caused by:
Not enough input arguments.
I tried to look into the error lines but I can't figure out where the error actually is.
Which function lacks fewer inputs? Is it referring to fun? Why would mle lack fewer inputs when it is trying to estimate the parameters?
Could someone kindly help me debug the error?
Thanks in advance.

exp() is a function, not a variable, precise the argument
exp^(-c*w) ---> exp(-c*w)
The starting point concerns the 6 parameters, not only one
0.1*ones(1,6)
In custcdf mle requires the upper bound of the integral to be a
scalar, I did some trial and error and the range is [2~9]. for the
trial some values lead to negative cdf or less than 1 discard them.
Then use the right one to compute the upper bound see if it's the
same as the one you predefined.
I re-write all the functions, check them out
The code is as follow
Censored = ones(5,1);% All data could be trusted
data = rand(5,1); % Since I cannot upload the acutal data, we may use this
f = #(w,a,b,c) (w.^(a-1)).*((1-w).^(b-1)).*exp(-c.*w);
% to estimate the parameters
custpdf = #(t,alpha,theta,beta, a,b,c)...
(((integral(#(w)f(w,a,b,c), 0,1)).^-1).*...
beta.*...
((igamma(alpha, (theta./t).^beta)).^(a-1)).*...
((theta./t).^(alpha.*beta + 1 )).*...
exp(-(((theta./t).^beta)+...
c.*igamma(alpha, (theta./t).^beta)./gamma(alpha))))./...
(theta.*...
((gamma(alpha)).^(a+b-1)).*...
((gamma(alpha)-...
igamma(alpha, (theta./t).^beta)).^(1-b)));
custcdf = #(t,alpha,theta,beta, a,b,c)...
((integral(#(w)f(w,a,b,c), 0,1)).^-1).*...
(integral(#(w)f(w,a,b,c), 0,2));
phat = mle(data,'pdf',custpdf,'cdf',custcdf,'start', 0.1.*ones(1,6),'Censoring',Censored);
Result
phat = 0.1017 0.1223 0.1153 0.1493 -0.0377 0.0902

Related

Using `lsqnonlin` with vector inputs

I have a question about using the lsqnonlin function.
In my case I have two functions:
f_1=#(t,x)sin(t+x.^2);
f_2=#(t,x)cos(x.^2)+3.*t.^2;
f = {f_1, f_2};
I want to find the values of the arguments t and x which would result in the least square error, defined as: f_1(t,x)^2+f_2(t,x)^2. In other words, argmin for LSE.
My code is as follow with initial guess [1,2]:
lsqnonlin(f,[1,2])
And I'm getting the error:
Error in lsqnonlin (line 196)
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue.
lsqnonlin can be used for vector function and vector input according to the documentation. I wonder how to prepare corresponding codes for it. Could anyone suggest the solution?
You are getting an error because lsqnonlin expects a scalar function handle that maps a vector to a vector, whereas you specify a cell array of function handles. To fix this, instead of a vector of functions outputting one scalar each, you need to rewrite it into a single function that accepts a vector of inputs and also outputs a vector:
f = #(xt)[sin(xt(2)+xt(1).^2), cos(xt(1).^2)+3.*xt(2).^2];
% xt = [x,t]
% f = [f_1(xt), f_2(xt)]
so f and xt are both vectors of 2 elements.
Then, the solver works:
lsqnonlin(f,[1,2])
ans =
1.6144 0.5354

Nonlinear least squares error in MATLAB

I am attempting to fit some data to a nonlinear equation in MATLAB. I am using the package lsqnonlin. I cannot seem to find out why I am getting an error in my estimation. My code looks as follows:
fun = #(x)x(1)*log(x(2)/v)-y;
x0 = [15,15];
lb = [15,15];
ub = [1000,1000];
options = optimoptions('lsqnonlin','Display','iter');
[x,resnorm,residual,exitflag,output] = lsqnonlin(fun,x0,lb, ub, options)
x
where v is my data. V ranges from 0.2 to ~14, so I set the lower bound to 15 so my function would always be defined. However, when I run the program I still get an error stating that the objective function is returned undefined values at initial point.
Any ideas are appreciated.

How to use fmincon to optimize two control vectors of a function

I have a function of 2 different vector. These are the control vector (decision variables) of the function. I want to use fmincon to optimize this function and also get the both control vector results separately.
I have tried to use handle ,#, but I got an error.
The function is:
function f = myFS(x,sv) % x is a vector (5,1)
f = norm(x)^2-sigma*(sv(1)+sv(2));
end
%% I tried to write fmincone to consider both control vectors (x and sv)
[Xtemp(:,h2),Fval, fiasco] = fmincon(#(x,sv)myFS(x,sv)...
,xstart,[],[],[],[],VLB,VUB,#(x,sv)myCon(sv),options);
Here is the error I get:
Error using myFS (line 12) Not enough input arguments.
Error in fmincon (line 564)
initVals.f =
feval(funfcn{3},X,varargin{:});
Error in main_Econstraint (line 58) [Xtemp(:,h2),Fval, fiasco] =
fmincon('myFS',xstart,[],[],[],[],VLB,VUB,#(x,sv)myCon(sv),options);
Thanks
fmincon expects your function to be of a single variable, there is no getting around that, but see:
http://se.mathworks.com/help/optim/ug/passing-extra-parameters.html
for example, if both x, cv are variables of the optimization you can combine them and then split them in the actual objective
for example
x_cv = vertcat(x, cv) and then x = x_cv(1:5); cv = x_cv(6:end)'
if cv is not a variable of the optimization, then 'freeze it' as the link above suggests

Octave fminsearch: Problems with minimization and options

I am trying to use Octave's fminsearch function, which I have used in MATLAB before. The function seems not sufficiently documented (for me at least), and I have no idea how to set to options such that it would actually minimize.
I tried fitting a very simple exponential function using the code at the end of this message. I want the following:
I want the function to take as input the x- and y-values, just like MATLAB would do. Furthermore, I want some control over the options, to make sure that it actually minimizes (i.e. to a minimum!).
Of course, in the end I want to fit functions that are more complicated than exponential, but I want to be able to fit exponentials at least.
I have several problems with fminsearch:
I tried handing over the x- and y-value to the function, but a matlab-style thing like this:
[xx,fval]=fminsearch(#exponential,[1000 1],x,y);
or
[xx,fval]=fminsearch(#exponential,[33000 1],options,x,y)
produces errors:
error: options(6) does not correspond to known algorithm
error: called from:
error: /opt/local/share/octave/packages/optim-1.0.6/fmins.m at line 72, column 16
error: /opt/local/share/octave/packages/optim-1.0.6/fminsearch.m at line 29, column 4
Or, respectively (for the second case above):
error: `x' undefined near line 4 column 3
error: called from:
error: /Users/paul/exponential.m at line 4, column 2
error: /opt/local/share/octave/packages/optim-1.0.6/nmsmax.m at line 63, column 6
error: /opt/local/share/octave/packages/optim-1.0.6/fmins.m at line 77, column 9
error: /opt/local/share/octave/packages/optim-1.0.6/fminsearch.m at line 29, column 4
Apparently, the order of arguments that fminsearch takes is different from the one in MATLAB. So, how is this order??
How can I make fminsearch take values and options?
I found a workaround to the problem that the function would not take values: I defined the x- and y values as global. Not elegant, but at least then the values are available in the function.
Nonetheless, fminsearch does not minimize properly.
This is shown below:
Here is the function:
function f=exponential(coeff)
global x
global y
X=x;
Y=y;
a= coeff(1);
b= coeff(2);
Y_fun = a .* exp(-X.*b);
DIFF = Y_fun - Y;
SQ_DIFF = DIFF.^2;
f=sum(SQ_DIFF);
end
Here is the code:
global x
global y
x=[0:1:200];
y=4930*exp(-0.0454*x);
options(10)=10000000;
[cc,fval]=fminsearch(#exponential,[5000 0.01])
This is the output:
cc =
4930.0 5184.6
fval = 2.5571e+08
Why does fminsearch not find the solution?
There is an fminsearch implementation in the octave-forge package "optim".
You can see in its implementation file that the third parameter is always an options vector, the fourth is always a grad vector, so your ,x,y invocations will not work.
You can also see in the implementation that it calls an fmins implementation.
The documentation of that fmins implementation states:
if options(6)==0 && options(5)==0 - regular simplex
if options(6)==0 && options(5)==1 - right-angled simplex
Comment: the default is set to "right-angled simplex".
this works better for me on a broad range of problems,
although the default in nmsmax is "regular simplex"
A recent problem of mine would solve fine with matlab's fminsearch, but not with this octave-forge implementation. I had to specify an options vector [0 1e-3 0 0 0 0] to have it use a regular simplex instead of a 'right-angled simplex'. The octave default makes no sense if your coefficients differ vastly in scale.
The optimization function fminsearch will always try to find a minimum, no matter what the options are. So if you are finding it's not finding a minimum, it's because it failed to do so.
From the code you provide, I cannot determine what goes wrong. The solution with the globals should work, and indeed does work over here, so something else on your side must be going awry. (NOTE: I do use MATLAB, not Octave, so those two functions could be slightly different...)
Anyway, why not do it like this?
function f = exponential(coeff)
x = 0:1:200;
y = 4930*exp(-0.0454*x);
a = coeff(1);
b = coeff(2);
Y_fun = a .* exp(-x.*b);
f = sum((Y_fun-y).^2);
end
Or, if you must pass x and y as external parameters,
x = [0:1:200];
y = 4930*exp(-0.0454*x);
[cc,fval] = fminsearch(#(c)exponential(c,x,y),[5000 0.01])
function f = exponential(coeff,x,y)
a = coeff(1);
b = coeff(2);
Y_fun = a .* exp(-x.*b);
f = sum((Y_fun-y).^2);
end

How to use multiple parameters with fittype in Matlab

I have a 1000x2 data file that I'm using for this problem.
I am supposed to fit the data with Acos(wt + phi). t is time, which is the first column in the data file, i.e. the independent variable. I need to find the fit parameters (A, f, and phi) and their uncertainties.
My code is as follows:
%load initial data file
data = load('hw_fit_cos_problem.dat');
t = data(:,1); %1st column is t (time)
x = t;
y = data(:,2); %2nd column is y (signal strength)
%define fitting function
f = fittype('A*cos(w*x + p)','coefficients','A','problem',{'w','p'});
% check fit parameters
coeffs = coeffnames(f);
%fit data
[A] = fit(x,y,f)
disp('confidence interval/errorbars');
ci = confint(A)
which yields 4 different error messages that I don't understand.
Error Messages:
Error using fit>iAssertNumProblemParameters (line 1113)
Missing problem parameters. Specify the values as a cell array with one element for each problem parameter
in the fittype.
Error in fit>iFit (line 198)
iAssertNumProblemParameters( probparams, probnames( model ) );
Error in fit (line 109)
[fitobj, goodness, output, convmsg] = iFit( xdatain, ydatain, fittypeobj, ...
Error in problem2 (line 14)
[A] = fit(x,y,f)
The line of code
f = fittype('A*cos(w*x + p)','coefficients','A','problem',{'w','p'});
specifies A as a "coefficient" in the model, and the values w and p as "problem" parameters.
Thus, the fitting toolbox expects that you will provide some more information about w and p, and then it will vary A. When no further information about w and p was provided to the fitting tool, that resulted in an error.
I am not sure of the goal of this project, or why w and p were designated as problem parameters. However, one simple solution is to allow the toolbox to treat A, w, and p as "coefficients", as follows:
f = fittype('A*cos(w*x + p)','coefficients', {'A', 'w', 'p'});
In this case, the code will not throw an error, and will return 95% confidence intervals on A, w, and p.
I hope that helps.
The straightforward answer to your question is that the error "Missing problem parameters" is generated because you have identified w and p as problem-specific fixed parameters,
but you have not told the fit function what these fixed values are.
You can do this by changing the line
[A] = fit(x,y,f)
to
[A]=fit(x,y,f,'problem',{100,0.1})
which supplies the values w=100 and p=0.1 in the fit. This should resolve the errors you specified (all 4 error messages result from this error)
In general specifying some of the quantities in your fit equation as problem-specific fixed parameters might be a valid thing to do - for example if you have determined them independently and have good reason to believe the values you obtained to be reliable. In this case, you might know the frequency w in this way, but you most probably won't know the phase p, so that should be a fit coefficient.
Hope that helps.