0001 function [img]= inv_solve_abs_annealingMetropolis_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
0036 n_parameters= size(img.params_mapping.params,1);
0037
0038 if isfield(inv_model.parameters,'temp')
0039 tempInit = inv_model.parameters.temp;
0040 tempfinale= inv_model.parameters.tempfinale;
0041 cooldown= inv_model.parameters.cooldown;
0042 nMetro= inv_model.parameters.nMetro;
0043 else
0044 tempInit = 1000;
0045 tempfinale= 0.01;
0046 cooldown= 0.95;
0047 nMetro= 300;
0048 end
0049
0050 if ~isfield(inv_model.parameters,'normalisation')
0051 img.parameters.normalisation= 1;
0052 end
0053
0054 if ~isfield(inv_model.params_mapping,'rangeParams')
0055 rangeParams= zeros(n_parameters,2);
0056 rangeParams(:,1)= -6; rangeParams(:,2)= 6;
0057 else
0058 rangeParams= inv_model.params_mapping.rangeParams;
0059 end
0060
0061 if ~isfield(inv_model.params_mapping,'alpha')
0062 alpha= 1;
0063 else
0064 alpha= inv_model.params_mapping.alpha;
0065 end
0066
0067 temp= tempInit; k= 1;
0068 while temp>=tempfinale
0069 temp= temp*cooldown;
0070 k=k+1;
0071 end
0072
0073 disp(['Number of iteration ' num2str(k)])
0074
0075
0076
0077
0078
0079
0080 if isfield(inv_model.params_mapping,'inital_model')
0081 model= inv_model.params_mapping.inital_model;
0082 else
0083 np= numel(inv_model.params_mapping.params);
0084 model= 10.^((rangeParams(np,1).*(rangeParams(:,2)-rangeParams(:,1))+rangeParams(:,1)));
0085 end
0086
0087
0088 img.params_mapping.params= model;
0089 cost= objectiveFunction(img,data,alpha);
0090 costRef= cost;
0091
0092
0093
0094
0095 temp= tempInit;
0096 n_temp= 1;
0097 while temp >= tempfinale
0098 for n= 1:nMetro
0099 model_try= model;
0100 idx_parametr= randi(n_parameters,1,1);
0101 model_try(idx_parametr)= (rand(1,1)*(rangeParams(idx_parametr,1))+rangeParams(idx_parametr,2));
0102 img.params_mapping.params= model_try;
0103 cost_try= objectiveFunction(img,data,alpha);
0104 if rand <= (exp(-cost_try/costRef)/exp(-cost/costRef))^(1/temp)
0105 likelihood= exp(-cost_try/costRef);
0106 cost= cost_try;
0107 model= model_try;
0108 end
0109 end
0110 resRec(n_temp)= cost;
0111 res_parRec(n_temp,:)= model';
0112 tempRec(n_temp)= temp;
0113 likelihoodRec(n_temp)= likelihood;
0114
0115 n_temp= n_temp+1;
0116 temp = temp*cooldown;
0117 end
0118 res_parRec(:,3:4)= 10.^res_parRec(:,3:4);
0119
0120 screenSize = get(0,'ScreenSize');
0121 h = figure;
0122 set(h,'Position',[0 0 screenSize(3)/2 screenSize(4)]);
0123 subplot(4,1,1)
0124 plot(tempRec,res_parRec(:,1),tempRec,res_parRec(:,2),'linewidth',2)
0125 set(gca,'fontsize',16,'fontname','Times','xDir','reverse','xScale','log')
0126 subplot(4,1,2)
0127 plot(tempRec,res_parRec(:,3),tempRec,res_parRec(:,4),'linewidth',2)
0128 set(gca,'fontsize',16,'fontname','Times','xDir','reverse','xScale','log','yScale','log')
0129 subplot(4,1,3)
0130 plot(tempRec,resRec,'linewidth',2)
0131 set(gca,'fontsize',16,'fontname','Times','xDir','reverse','xScale','log','yScale','log')
0132 subplot(4,1,4)
0133 plot(tempRec,likelihoodRec,'linewidth',2)
0134 set(gca,'fontsize',16,'fontname','Times','xDir','reverse','xScale','log')
0135
0136 [res_parRec(end,1) res_parRec(end,2)]
0137 [res_parRec(end,3) res_parRec(end,4)]
0138
0139 end
0140
0141 function cost= objectiveFunction(img,data,alpha)
0142 vsim= fwd_solve(img);
0143 residuals= img.parameters.normalisation*(vsim.meas-data);
0144 cost= sqrt(sum(residuals.^2))/alpha;
0145 end
0146
0147
0148 function do_unit_test
0149 shape_str = ['solid top = plane(0,0,0;0,1,0);\n' ...
0150 'solid mainobj= top and orthobrick(-100,-200,-100;410,10,100) -maxh=20.0;\n'];
0151 e0 = linspace(0,310,64)';
0152 elec_pos = [e0,0*e0,0*e0,1+0*e0,0*e0,0*e0];
0153 elec_shape= [0.1,0.1,1];
0154 elec_obj = 'top';
0155 fmdl = ng_mk_gen_models(shape_str, elec_pos, elec_shape, elec_obj);
0156 fmdl.stimulation= stim_pattern_geophys( 64, 'Wenner', {'spacings', 1:32} );
0157
0158 img= mk_image(fmdl,1/20);
0159 fm_pts= interp_mesh(fmdl);
0160 x_bary= fm_pts(:,1); z_bary= fm_pts(:,2);
0161
0162 z_params= (min(fmdl.nodes(:,2)):max(fmdl.nodes(:,2)))';
0163 a = 0.36; b = 130;
0164 x_params= a*z_params+b;
0165 xlim=interp1(z_params,x_params,z_bary);
0166 img.elem_data(x_bary>xlim)= 1/120;
0167
0168 dd = fwd_solve(img);
0169 sig= sqrt(norm(dd.meas)); m= size(dd.meas,1);
0170 noise= .05;
0171 ddn= dd;
0172 ddn.meas = dd.meas + noise*sig*randn(m,1);
0173
0174 img1= mk_image(fmdl,1);
0175 vh1= fwd_solve(img1);
0176 normalisation= 1./vh1.meas;
0177 I= speye(length(normalisation));
0178 I(1:size(I,1)+1:size(I,1)*size(I,1))= normalisation;
0179
0180 a = 0.3; b = 150;
0181 res_params= log([10 100]');
0182
0183 z_params= (min(fmdl.nodes(:,2)):max(fmdl.nodes(:,2)))';
0184 x_params= a*z_params+b;
0185
0186 imdl = eidors_obj('inv_model','testNoisy');
0187 imdl.fwd_model= fmdl;
0188 imdl.params_mapping.params= [a; b ; res_params];
0189 imdl.params_mapping.perturb= [0.1; 50; 2 ; 2];
0190
0191 imdl.params_mapping.function = @border_mapping;
0192 imdl.params_mapping.data.x_bary = x_bary;
0193 imdl.params_mapping.data.z_bary = z_bary;
0194 imdl.params_mapping.data.res_params = res_params;
0195 imdl.params_mapping.data.x_params = x_params;
0196 imdl.params_mapping.data.z_params = z_params;
0197 imdl.params_mapping.data.a = a;
0198 imdl.params_mapping.data.b = b;
0199 imdl.reconst_type= 'absolute';
0200 imdl.solve = @inv_solve_abs_annealingSimplex_params;
0201 imdl.normalize_measurements= 1;
0202 imdl.parameters.normalisation= I;
0203
0204 imdl.parameters.temp= 1000;
0205 imdl.parameters.tempfinale= 1;
0206 imdl.parameters.cooldown= 0.97;
0207 imdl.parameters.nMetro= 1;
0208 imdl.jacobian_bkgnd.value = 1;
0209
0210 imgr= inv_solve(imdl, ddn);
0211 img = mk_image( imdl );
0212 img.elem_data= imgr.elem_data;
0213 vAS= fwd_solve(img); vAS = vAS.meas;
0214
0215 figure; hist(I*(dd.meas-vAS),50)
0216 show_pseudosection( fmdl, I*dd.meas, 'HorizontalDownward')
0217 show_pseudosection( fmdl, I*vAS, 'HorizontalDownward')
0218 show_pseudosection( fmdl, (vAS-dd.meas)./dd.meas*100,'HorizontalDownward')
0219
0220 end
0221
0222
0223 function img = border_mapping(img)
0224
0225 z= img.params_mapping.data.z_params;
0226 res= img.params_mapping.params(end-1:end);
0227
0228 a= img.params_mapping.params(1);
0229 b= img.params_mapping.params(2);
0230 x= z*a+b;
0231
0232 xi= img.params_mapping.data.x_bary;
0233 zi= img.params_mapping.data.z_bary;
0234 xlim=interp1(z,x,zi);
0235
0236 vi= zeros(size(img.fwd_model.elems,1),1) + res(1);
0237 vi(xi>xlim)= res(2);
0238
0239 img.elem_data= exp(-vi);
0240
0241 img.params_mapping.data.x_params = x;
0242 img.params_mapping.params= [a ; b ; res];
0243
0244 end
0245