Thursday, November 8, 2012

How to hold parameters in nlinfit (Matlab)

If you are using nlinfit to fit your data in Matlab, maybe you are interested (as I was) in finding an easy way to hold some of your parameters (by default there no option to do it).
So how to hold, how to fix some of the parameters?

Looking on the Internet I found this "official" solution link coming directly from the Mathworks support.
It consists in re-writing a new version of nlinfit, called nlinfitsome, that fits only some of parameters. 
The solution is pretty nice and clever but it has a drawback.

The reason I use nlinfit over lsqcurvefit is because it makes relatively easy to get the error bars, however with the proposed solution this advantage is lost so I modified nlinfitsome to address this specific problem.

My function, called mod_nlinfit, has exactly the same arguments of nlinfit and gives you as output the parameters and their error bars. I know that nlinfit has a richer output, but for my needs, having the parameters and error bars is enough.

The code is quite straightforward.

NB
The hold parameters will have no uncertainty.

Credits:
Mathworks support


Matlab code:


function [p, r,  err]=mod_nlinfit(fixed, x, y, fun, beta0, varargin)
% [p, err]=mod_nlinfit(fixed, x, y, fun, beta0, varargin)
% p: vector containing the fitting results

% r: residuals
% err: error bars of the parameters
% fixed is a vector of the same length of beta0 and containing logical elements (i.e. true and
% false). True values mean FIXED parameters.
% EXAMPLE
% If you have three parameters, a vector fixed [true true false]
% means that only the third parameter will change



% all the values in beta0 are copied in p however only the free (NOT fixed)
% ones will change

p=beta0;

% fixed parameters will get zero uncertainity

err=zeros(size(beta0));

% extraction of the free parameters

beta1=beta0(~fixed);

[p1, r1, JJ1] = nlinfit(x,y,@nested_fun,beta1,varargin{:});

% getting the error bars for the free parameters
delta=nlparci(p1, r1, JJ1);
err1=(delta(:, 2)- delta(:, 1))/2;

% update the parameters
p(~fixed)=p1;

%residuals
r=r1;

% ... and the error bars
err(~fixed)=err1;

    % Nested function takes just the parameters to be estimated as inputs
    % It inherits the following from the outer function:
    %   fixed = logical index for fixed elements
    %   beta0 = original guess for the parameters

    function yy=nested_fun(beta, x)
       
        b(fixed)=beta0(fixed);
        b(~fixed)=beta;
       
        yy=fun(b, x);

    end
end




NOTE
This code is used in edufit

2 comments:

  1. Hi,
    Thanks for teh useful code. However when I run it, it gives me an error :
    Attempt to execute SCRIPT varargin as a function.
    Please could you helm me solve that

    ReplyDelete

Your comment will be visible after approval.