0001 function [img]= inv_solve_abs_annealingSimplex_params(inv_model, data)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 if ischar(inv_model) && strcmp(inv_model,'UNIT_TEST'); do_unit_test; return; end
0027
0028 if isfield(inv_model,'params_mapping') && isfield(inv_model.params_mapping,'function')
0029 mapping_function= inv_model.params_mapping.function;
0030 img= feval(mapping_function,inv_model);
0031 else
0032 error('The inverse model must contain a field "params_mapping" where a mapping function links the forward and inverse parameters');
0033 end
0034
0035 if isfield(inv_model.parameters,'temp')
0036 tempInit = inv_model.parameters.temp;
0037 tempfinale= inv_model.parameters.tempfinale;
0038 cooldown= inv_model.parameters.cooldown;
0039 nMetro= inv_model.parameters.nMetro;
0040 else
0041 tempInit = 1000;
0042 tempfinale= 0.01;
0043 cooldown= 0.95;
0044 nMetro= 3;
0045 end
0046
0047 if ~isfield(inv_model.parameters,'normalisation')
0048 img.parameters.normalisation= 1;
0049 end
0050 temp= tempInit; k= 1;
0051 while temp>=tempfinale
0052 temp= temp*cooldown;
0053 k=k+1;
0054 end
0055 D= zeros(k,1); temperature= zeros(k,1);
0056 niter= k;
0057 temp= tempInit; k= 1;
0058
0059
0060 np= size(img.params_mapping.params,1);
0061
0062
0063
0064
0065 if isfield(inv_model.params_mapping,'inital_model')
0066 modeles= inv_model.params_mapping.inital_model;
0067 else
0068 modeles= randn(np,np+1).*repmat(inv_model.params_mapping.perturb,1,np+1) + ...
0069 repmat(inv_model.params_mapping.params,1,np+1);
0070 modelesr= modeles(end,:);
0071 keep= ismember(modeles(end,:)<modeles(end-1,:),1);
0072 modeles(end,keep)= modeles(end-1,keep);
0073 modeles(end-1,keep)= modelesr(keep);
0074 end
0075 modelesT= [];
0076 costhhi= [];
0077 modelesLo= [];
0078
0079
0080 cost= zeros(1,np+1);
0081 for j= 1:np+1
0082 img.params_mapping.params= modeles(:,j);
0083 cost(j)= objectiveFunction(img,data);
0084 end
0085 dist= 1;
0086
0087 while temp>=tempfinale && dist >= 1e-5
0088 for i= 1:nMetro
0089 [costlo,ilo]= min(cost);
0090 [costhi,ihi]= max(cost);
0091 [costnhi]= max(setdiff(cost,costhi));
0092 bary= sum(modeles,2);
0093
0094 [modtryReflection,costtryReflection]= deformation(modeles,bary,np,ihi,-1,img,data);
0095 boolean1= annealingProbability(costtryReflection,costlo,temp);
0096 boolean2= annealingProbability(costtryReflection,costnhi,temp);
0097 if boolean1
0098
0099 [modtryExpansion,costtryExpansion]= deformation(modeles,bary,np,ihi,-2,img,data);
0100 boolean= annealingProbability(costtryExpansion,costtryReflection,temp);
0101 if boolean
0102 modeles(:,ihi)= modtryExpansion;
0103 cost(ihi)= costtryExpansion;
0104 else
0105 modeles(:,ihi)= modtryReflection;
0106 cost(ihi)= costtryReflection;
0107 end
0108 elseif boolean2
0109
0110 [modtryOutContraction,costtryOutContraction]= deformation(modeles,bary,np,ihi,-0.7,img,data);
0111 boolean= annealingProbability(costtryOutContraction,costtryReflection,temp);
0112 if boolean
0113 modeles(:,ihi)= modtryOutContraction;
0114 cost(ihi)= costtryOutContraction;
0115 else
0116 modeles(:,ihi)= modtryReflection;
0117 cost(ihi)= costtryReflection;
0118 end
0119 else
0120
0121 [modtryContraction,costtryContraction]= deformation(modeles,bary,np,ihi,0.7,img,data);
0122 boolean= annealingProbability(costtryContraction,costhi,temp);
0123 if boolean
0124 modeles(:,ihi)= modtryContraction;
0125 cost(ihi)= costtryContraction;
0126 else
0127 modeles= (modeles+repmat(modeles(:,ilo),1,np+1))/2;
0128 for j= 1:np+1
0129 img.params_mapping.params= modeles(:,j);
0130 cost(j)= objectiveFunction(img,data);
0131 end
0132 end
0133 end
0134 costhi= max(cost);
0135 modelesT= [modelesT modeles];
0136 costhhi= [costhhi ; costhi];
0137 [costlo,ilo]= min(cost);
0138 modelesLo= [modelesLo modeles(:,ilo)];
0139 end
0140
0141
0142
0143
0144
0145 temperature(k)= temp;
0146
0147 temp= temp*cooldown;
0148 niter= niter-1;
0149 k=k+1;
0150
0151
0152
0153
0154
0155 if k>2 && D(k)>D(k-1); break; end
0156 end
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 [costlo,ilo]= min(cost);
0168 img.params_mapping.params= modeles(:,ilo);
0169 img= feval(mapping_function,img);
0170
0171
0172 modeles(1:end-2,ilo);
0173 exp(modeles(end-1:end,ilo));
0174
0175 v= 1:size(modelesLo,2);
0176
0177 figure; plot(v,exp(modelesLo),'linewidth',2);
0178 xlabel('Iteration number','fontsize',20,'fontname','Times')
0179 ylabel('Inversion parameter','fontsize',20,'fontname','Times');
0180 set(gca,'fontsize',15,'fontname','Times');
0181 axis tight;
0182
0183
0184
0185 figure; semilogy(reshape(costhhi,[],1),'k','linewidth',2)
0186 xlabel('Iteration number','fontsize',20,'fontname','Times')
0187 ylabel('Cost function','fontsize',20,'fontname','Times')
0188 set(gca,'fontsize',15,'fontname','Times'); drawnow
0189
0190
0191 end
0192
0193 function [boolean,Pr]= annealingProbability(costtry,costhi,temp)
0194 E= (costtry-costhi)/temp;
0195 Ptry= exp(-E);
0196 Pr= min([1 Ptry]);
0197 boolean= 0;
0198 if Pr > rand ; boolean= 1; end
0199 end
0200
0201
0202 function cost= objectiveFunction(img,data)
0203 vsim= fwd_solve(img);
0204 residuals= img.parameters.normalisation*(vsim.meas-data);
0205 cost= sqrt(sum(residuals.^2));
0206 end
0207
0208 function [modtry,costtry]= deformation(modeles,bary,np,ihi,fac,img,data)
0209
0210 fac1= (1-fac)/np;
0211 fac2= fac1-fac;
0212
0213 modtry= bary*fac1-modeles(:,ihi)*fac2;
0214
0215 imgtry= img;
0216 imgtry.params_mapping.params= modtry;
0217 costtry= objectiveFunction(imgtry,data);
0218 end
0219
0220
0221
0222 function do_unit_test
0223 shape_str = ['solid top = plane(0,0,0;0,1,0);\n' ...
0224 'solid mainobj= top and orthobrick(-100,-200,-100;410,10,100) -maxh=20.0;\n'];
0225 e0 = linspace(0,310,64)';
0226 elec_pos = [e0,0*e0,0*e0,1+0*e0,0*e0,0*e0];
0227 elec_shape= [0.1,0.1,1];
0228 elec_obj = 'top';
0229 fmdl = ng_mk_gen_models(shape_str, elec_pos, elec_shape, elec_obj);
0230 fmdl.stimulation= stim_pattern_geophys( 64, 'Wenner', {'spacings', 1:32} );
0231
0232 img= mk_image(fmdl,1/20);
0233 fm_pts= interp_mesh(fmdl);
0234 x_bary= fm_pts(:,1); z_bary= fm_pts(:,2);
0235
0236 z_params= (min(fmdl.nodes(:,2)):max(fmdl.nodes(:,2)))';
0237 a = 0.36; b = 130;
0238 x_params= a*z_params+b;
0239 xlim=interp1(z_params,x_params,z_bary);
0240 img.elem_data(x_bary>xlim)= 1/120;
0241
0242 dd = fwd_solve(img);
0243 sig= sqrt(norm(dd.meas)); m= size(dd.meas,1);
0244 noise= .05;
0245 ddn= dd;
0246 ddn.meas = dd.meas + noise*sig*randn(m,1);
0247
0248 img1= mk_image(fmdl,1);
0249 vh1= fwd_solve(img1);
0250 normalisation= 1./vh1.meas;
0251 I= speye(length(normalisation));
0252 I(1:size(I,1)+1:size(I,1)*size(I,1))= normalisation;
0253
0254 a = 0.3; b = 150;
0255 res_params= log([10 100]');
0256
0257 z_params= (min(fmdl.nodes(:,2)):max(fmdl.nodes(:,2)))';
0258 x_params= a*z_params+b;
0259
0260 imdl = eidors_obj('inv_model','testNoisy');
0261 imdl.fwd_model= fmdl;
0262 imdl.params_mapping.params= [a; b ; res_params];
0263 imdl.params_mapping.perturb= [0.1; 50; 2 ; 2];
0264
0265 imdl.params_mapping.function = @border_mapping;
0266 imdl.params_mapping.data.x_bary = x_bary;
0267 imdl.params_mapping.data.z_bary = z_bary;
0268 imdl.params_mapping.data.res_params = res_params;
0269 imdl.params_mapping.data.x_params = x_params;
0270 imdl.params_mapping.data.z_params = z_params;
0271 imdl.params_mapping.data.a = a;
0272 imdl.params_mapping.data.b = b;
0273 imdl.reconst_type= 'absolute';
0274 imdl.solve = @inv_solve_abs_annealingSimplex_params;
0275 imdl.normalize_measurements= 1;
0276 imdl.parameters.normalisation= I;
0277
0278 imdl.parameters.temp= 1000;
0279 imdl.parameters.tempfinale= 1;
0280 imdl.parameters.cooldown= 0.97;
0281 imdl.parameters.nMetro= 1;
0282 imdl.jacobian_bkgnd.value = 1;
0283
0284 imgr= inv_solve(imdl, ddn);
0285 img = mk_image( imdl );
0286 img.elem_data= imgr.elem_data;
0287 vAS= fwd_solve(img); vAS = vAS.meas;
0288
0289 figure; hist(I*(dd.meas-vAS),50)
0290 show_pseudosection( fmdl, I*dd.meas, 'HorizontalDownward')
0291 show_pseudosection( fmdl, I*vAS, 'HorizontalDownward')
0292 show_pseudosection( fmdl, (vAS-dd.meas)./dd.meas*100,'HorizontalDownward')
0293
0294 end
0295
0296
0297 function img = border_mapping(img)
0298
0299 z= img.params_mapping.data.z_params;
0300 res= img.params_mapping.params(end-1:end);
0301
0302 a= img.params_mapping.params(1);
0303 b= img.params_mapping.params(2);
0304 x= z*a+b;
0305
0306 xi= img.params_mapping.data.x_bary;
0307 zi= img.params_mapping.data.z_bary;
0308 xlim=interp1(z,x,zi);
0309
0310 vi= zeros(size(img.fwd_model.elems,1),1) + res(1);
0311 vi(xi>xlim)= res(2);
0312
0313 img.elem_data= exp(-vi);
0314
0315 img.params_mapping.data.x_params = x;
0316 img.params_mapping.params= [a ; b ; res];
0317
0318 end
0319