1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
function [p,err]=datafit(imp,G,varargin)
//
// [p,err]=datafit([imp,] G [,DG],Z [,W],...)
//
// Function used for fitting data to a model.
// For a given function G(p,z), this function finds the best vector
// of parameters p for approximating G(p,z_i)=0 for a set of measurement
// vectors z_i. Vector p is found by minimizing
// G(p,z_1)'WG(p,z_1)+G(p,z_2)'WG(p,z_2)+...+G(p,z_n)'WG(p,z_n)
//
// G: Scilab function (e=G(p,z), e: nex1, p: npx1, z: nzx1)
// p0: initial guess (size npx1)
// Z: matrix [z_1,z_2,...z_n] where z_i (nzx1) is the ith measurement
// W: weighting matrix of size nexne (optional)
// DG: partial of G wrt p (optional; S=DG(p,z), S: nexnp)
//
// Examples
//
//deff('y=FF(x)','y=a*(x-b)+c*x.*x')
//X=[];Y=[];
//a=34;b=12;c=14;for x=0:.1:3, Y=[Y,FF(x)+100*(rand()-.5)];X=[X,x];end
//Z=[Y;X];
//deff('e=G(p,z)','a=p(1),b=p(2),c=p(3),y=z(1),x=z(2),e=y-FF(x)')
//[p,err]=datafit(G,Z,[3;5;10])
//xset('window',0)
//xbasc();
//plot2d(X',Y',-1)
//plot2d(X',FF(X)',5,'002')
//a=p(1),b=p(2),c=p(3);plot2d(X',FF(X)',12,'002')
//
//a=34;b=12;c=14;
//deff('s=DG(p,z)','y=z(1),x=z(2),s=-[x-p(2),-p(1),x*x]')
//[p,err]=datafit(G,DG,Z,[3;5;10])
//xset('window',1)
//xbasc();
//plot2d(X',Y',-1)
//plot2d(X',FF(X)',5,'002')
//a=p(1),b=p(2),c=p(3);plot2d(X',FF(X)',12,'002')
//
//
// Copyright INRIA
[lhs,rhs]=argn(0)
if type(imp)<>1 then
varargin(0)=G
G=imp
imp=0
end
if type(G)==15 then
Gparams=G;Gparams(1)=null();
G=G(1)
else
Gparams=list()
end
DG=varargin(1)
if type(DG)==10|type(DG)==11|type(DG)==13 then
GR=%t //Jacobian provided
varargin(1)=null()
elseif type(DG)==15 then
error('Jacobian cannot be a list, parameters must be set in G')
else
GR=%f
end
Z=varargin(1);
varargin(1)=null()
if type(Z)<>1 then
error('datafit : wrong measurement matrix')
end
nv=size(varargin)
if nv>=1 then
if size(varargin(1),2)==1 then // p0 ou 'b'
W=1
else
W=varargin(1);varargin(1)=null()
if size(W,1)~=size(W,2) then
error('Weighting matrix must be square');
end
end
end
if type(varargin(1))==1 then // p0
p0=varargin(1)
else
p0=varargin(4)
end
[mz,nz]=size(Z);np=size(p0,'*');
if type(G)==10 then //form function to call hard coded external
if size(Gparams)==0 then
error('With hard coded function, user must give output size of G'),
end
m=Gparams(1);Gparams(1)=null()
// foo(m,np,p,mz,nz,Z,pars,f)
deff('f=G(p,Z)','f=call('''+G+''','+..
'm,1,''i'',np,2,''i'',p,3,''d'',mz,4,''i'',nz,5,''i'',Z,6,''d'','+..
'pars,7,''out'',['+string(m)+',1],8,''d'')')
pars=[];
for k=1:size(Gparams)
p=Gparams(k)
pars=[pars;p(:)]
end
Gparams=list()
end
if type(DG)==10 then //form function to call hard coded external
// dfoo(m,np,p,mz,nz,Z,pars,f)
deff('f=DG(p,Z)','f=call('''+DG+''','+..
'm,1,''i'',np,2,''i'',p,3,''d'',mz,4,''i'',nz,5,''i'',Z,6,''d'','+..
'pars,7,''out'',['+string(m)+','+string(np)+'],8,''d'')')
end
// form square cost gradient function DGG
if Gparams==list() then
GP = 'G(p,Z(:,i))'
GPPV = 'G(p+v,Z(:,i))'
DGP = 'DG(p,Z(:,i))'
else
GP = 'G(p,Z(:,i),Gparams(:))'
GPPV = 'G(p+v,Z(:,i),Gparams(:))'
DGP = 'DG(p,Z(:,i),Gparams(:))'
end
if ~GR then // finite difference
DGG=['g=0*p';
'pa=sqrt(%eps)*(1+1d-3*abs(p))'
'f=0;'
'for i=1:'+string(nz)
' g1='+GP
' f=f+g1''*W*g1'
'end'
'for j=1:'+string(np)
' v=0*p;v(j)=pa(j),'
' e=0;'
' for i=1:'+string(nz)
' g1='+GPPV
' e=e+g1''*W*g1'
' end'
' g(j)=e-f;'
'end;'
'g=g./pa;']
else // using Jacobian of G
DGG='g=0;for i=1:nz,g=g+2*'+DGP+'''*W*'+GP+',end'
end
// form cost function for optim
deff('[f,g,ind]=costf(p,ind)',[
'if ind==2|ind==4 then '
' f=0;'
' for i=1:'+string(nz)
' g1='+GP
' f=f+g1''*W*g1'
' end'
'else '
' f=0;'
'end';
'if ind==3|ind==4 then'
DGG
'else'
' g=0*p;'
'end'])
[err,p]=optim(costf,varargin(:),imp=imp)
endfunction
|