0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
1 % GETJACOBIAN Calculate Jacobian of a given model function.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
3 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
4 % DESCRIPTION
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
5 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
6 % Calculate Jacobian of a given model function for the given set of
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
7 % coefficients. Jacobian is approximated with finite difference method.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
8 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
9 % CALL:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
10 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
11 % J = getjacobian(coeff,model,X)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
12 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
13 % INPUT:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
14 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
15 % J - fit coefficients
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
16 % model - model function
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
17 % X - x vactor (abscissa)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
18 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
19 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
20 % OUTPUT:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
21 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
22 % J - Jacobian
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
23 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
24 % Note: Look at nlinfit.m of the stats toolbox. Model should be a matlab
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
25 % function calculating Model values as a function of X and of coefficients
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
26 % NOTE: The function prefer to work with column objects. Therefore it is
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
27 % good practise to directly input coeff and X as column objects
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
28 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
29 % Examples:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
30 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
31 % Use @ to specify MODELFUN:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
32 % load reaction;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
33 % J = getjacobian(coeff,@mymodel,X);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
34 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
35 % where MYMODEL is a MATLAB function such as:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
36 % function yhat = mymodel(beta, X)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
37 % yhat = (beta(1)*X(:,2) - X(:,3)/beta(5)) ./ ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
38 % (1+beta(2)*X(:,1)+beta(3)*X(:,2)+beta(4)*X(:,3));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
39 % or
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
40 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
41 % mymodel = @(beta,X)(beta(1).*X(:,1)+beta(2).*X(:,2)+...)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
42 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
44 % VERSION: $Id: getjacobian.m,v 1.1 2009/03/26 16:26:05 luigi Exp $
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
45 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
46 % HISTORY: 26-03-2009 L Ferraioli
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
47 % Creation
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
49
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
50 function J = getjacobian(coeff,model,X)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
51 % checking size, willing to work with columns
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
52 [a,b] = size(coeff);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
53 if a<b
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
54 coeff = coeff.';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
55 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
56 [a,b] = size(X);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
57 if a<b
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
58 X = X.';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
59 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
60
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
61 % finite difference relative step
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
62 fdiffstep = eps^(1/3);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
63 % evaluate model on the input coefficients
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
64 yfit = model(coeff,X);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
65 % check for NaNs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
66 nans = isnan(yfit(:));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
67
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
68 % initialization
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
69 p = numel(coeff);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
70 delta = zeros(size(coeff));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
71 J = zeros(numel(yfit),p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
72 for k = 1:p
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
73 if (coeff(k) == 0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
74 nb = sqrt(norm(coeff));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
75 delta(k) = fdiffstep * (nb + (nb==0));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
76 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
77 delta(k) = fdiffstep*coeff(k);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
78 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
79 yplus = model(coeff+delta,X);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
80 dy = yplus(:) - yfit(:);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
81 dy(nans) = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
82 J(:,k) = dy/delta(k);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
83 delta(k) = 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
84 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
85 end |