Search code examples
matlabmlefminsearch

Using fminsearch for parameter estimation


I am trying to find log Maximum likelihood estimation for Gaussian distribution, in order to estimate parameters. I know that Matlab has a built-in function that does this by fitting a Gaussian distribution, but I need to do this with logMLE in order to expand this method later for other distributions. So here is the log-likelihood function for gaussian dist : Gaussian Log MLE

And I used this code to estimate the parameters for a set of variables (r) with fminsearch. but my search does not coverage and I don't fully understand where is the problem:

clear
clc
close all
%make random numbers with gaussian dist
r=[2.39587291079469
1.57478022109723
-0.442284350603745
4.39661178526569
7.94034385633171
7.52208574723178
5.80673144943155
-3.11338531920164
6.64267230284774
-2.02996003947964];
% mu=2 sigma=3

%introduce f
f=@(x,r)-(sum((-0.5.*log(2*3.14.*(x(2))))-(((r-(x(2))).^2)./(2.*(x(1))))))
fun = @(x)f(x,r);

% starting point
x0 = [0,0];
 [y,fval,exitflag,output] = fminsearch(fun,x0)


f = 
    @(x,r)-(sum((-0.5.*log(2*3.14.*(x(2))))-(((r-(x(2))).^2)./(2.*(x(1))))))


Exiting: Maximum number of function evaluations has been exceeded
         - increase MaxFunEvals option.
         Current function value: 477814.233176 
y = 1×2    
1.0e+-3 *

    0.2501   -0.0000

fval = 4.7781e+05 + 1.5708e+01i
exitflag = 0
output = 
    iterations: 183
     funcCount: 400
     algorithm: 'Nelder-Mead simplex direct search'
       message: 'Exiting: Maximum number of function evaluations has been exceeded↵         - increase MaxFunEvals option.↵         Current function value: 477814.233176 ↵' 

Solution

  • Rewrite f as follows:

    enter image description here

    function y = g(x, r)
    
         n = length(r);
    
         log_part = 0.5.*n.*log(x(2).^2);
    
         sum_part = ((sum(r-x(1))).^2)./(2.*x(2).^2);
    
         y = log_part + sum_part;
    
     end
    

    Use fmincon instead of fminsearch because standard deviation is always a positif number.

    Set standard deviation lower bound to zero 0


    The entire code is as follows:

    %make random numbers with gaussian dist
    r=[2.39587291079469
    1.57478022109723
    -0.442284350603745
    4.39661178526569
    7.94034385633171
    7.52208574723178
    5.80673144943155
    -3.11338531920164
    6.64267230284774
    -2.02996003947964];
    % mu=2 sigma=3
    
    fun = @(x)g(x, r);
    % starting point
    x0 = [0,0];
    
    % borns 
    lb = [-inf, 0];
    ub = [inf, inf];
    [y, fval] = fmincon(fun,x0,[],[],[],[],lb,ub, []);
    function y = g(x, r)
    
         n = length(r);
    
         log_part = 0.5.*n.*log(x(2).^2);
    
         sum_part = ((sum(r-x(1))).^2)./(2.*x(2).^2);
    
         y = log_part + sum_part;
    end
    

    Solution

    y = [3.0693    0.0000]
    

    For better estimation use mle() directly

    The code is quiet simple:

    y = mle(r,'distribution','normal')
    

    Solution

    y = [3.0693    3.8056]