0001 function [NF,SE] = calc_noise_figure( inv_model, hp, iterations)
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
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 if nargin>=2
0045 inv_model.hyperparameter.value= hp;
0046
0047 try; inv_model.hyperparameter = rmfield(inv_model.hyperparameter,'func'); end
0048 end
0049 [inv_model, h_data, c_data] = process_parameters( inv_model );
0050
0051
0052
0053 if nargin<3; iterations= 10; end
0054 [NF,SE]= nf_calc_random( inv_model, h_data, c_data, iterations);
0055 eidors_msg('calculating NF=%f', NF, 2);
0056
0057 function [inv_model, h_data, c_data] = process_parameters( inv_model );
0058
0059 if isfield(inv_model.hyperparameter,'tgt_elems')
0060 [h_data, c_data]= simulate_targets( inv_model.fwd_model, ...
0061 inv_model.hyperparameter.tgt_elems);
0062 elseif isfield(inv_model.hyperparameter,'tgt_data')
0063 tgt_data= inv_model.hyperparameter.tgt_data;
0064 h_data= tgt_data.meas_t1;
0065 c_data= tgt_data.meas_t2;
0066 else
0067 error('unsure how to get data to measure signal');
0068 end
0069
0070
0071
0072 if isfield(inv_model.hyperparameter,'func')
0073 funcname= inv_model.hyperparameter.func;
0074 if strcmp( class(funcname), 'function_handle')
0075 funcname= func2str(funcname);
0076 end
0077
0078 if strcmp(funcname, 'choose_noise_figure')
0079 error('specifying inv_model.hp.func = choose_noise_figure will recurse');
0080 end
0081 end
0082
0083
0084 function NF= nf_calc_use_matrix( inv_model, h_data, c_data)
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 VOL = get_elem_volume(inv_model.fwd_model)';
0103
0104
0105 d_len = size(h_data,1);
0106 delta = 1e-2* mean(h_data);
0107 c_noise = c_data*ones(1,d_len) + eye(d_len);
0108 h_full = h_data*ones(1,d_len);
0109
0110 sig_data = mean(abs( ...
0111 calc_difference_data( h_data, c_data , inv_model.fwd_model ) ...
0112 ));
0113 var_data = mean(sum( ...
0114 calc_difference_data( h_full, c_noise, inv_model.fwd_model ) ...
0115 .^2, 2));
0116
0117
0118
0119
0120 [img0, img0n] = get_images( inv_model, h_data, c_data, ...
0121 h_full, c_noise);
0122
0123 i_len = length(img0);
0124 sig_img= VOL*abs(img0) / i_len;;
0125 var_img= VOL.^2*sum(img0n.^2 ,2) / i_len;
0126
0127 NF = ( sig_data/ sqrt(var_data) ) / ( sig_img / sqrt(var_img) );
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 function [h_data, c_data]= simulate_targets( fwd_model, ctr_elems)
0139
0140 homg= 1;
0141
0142
0143 sigma= homg*ones( size(fwd_model.elems,1) ,1);
0144
0145 img= eidors_obj('image', 'homogeneous image', ...
0146 'elem_data', sigma, ...
0147 'fwd_model', fwd_model );
0148 h_data=fwd_solve( img );
0149 h_data= h_data.meas;
0150
0151
0152 delta = 1e-2;
0153 sigma(ctr_elems) = homg*(1 + delta);
0154 img.elem_data = sigma;
0155 c_data=fwd_solve( img );
0156 c_data= c_data.meas;
0157
0158 function [img0, img0n] = get_images( inv_model, h_data, c_data, ...
0159 h_full, c_noise);
0160 if isa(inv_model.solve,'function_handle')
0161 solve= func2str(inv_model.solve);
0162 else
0163 solve= inv_model.solve;
0164 end
0165
0166
0167 switch solve
0168 case 'ab_tv_diff_solve'
0169 error('Dont know how to calculate TV noise figure')
0170
0171 case 'inv_kalman_diff'
0172 inv_model.inv_kalman_diff.keep_K_k1= 1;
0173 stablize = 6;
0174 img0 = inv_solve( inv_model, h_data, ...
0175 c_data*ones(1,stablize) );
0176 K= img0.inv_kalman_diff.K_k1;
0177 img0.elem_data = K*calc_difference_data( h_data , c_data , inv_model.fwd_model);
0178 img0n.elem_data= K*calc_difference_data( h_full , c_noise, inv_model.fwd_model);
0179
0180 otherwise
0181 img0 = inv_solve( inv_model, h_data, c_data);
0182 if nargin>4
0183 img0n= inv_solve( inv_model, h_full, c_noise);
0184 end
0185 end
0186
0187
0188 if isfield(img0,'node_data');
0189 img0 = img0.node_data;
0190 else
0191 img0 = img0.elem_data;
0192 end
0193
0194 if isfield(img0n,'node_data');
0195 img0n = img0n.node_data;
0196 else
0197 img0n = img0n.elem_data;
0198 end
0199
0200
0201 function NF= nf_calc_iterate( inv_model, h_data, c_data);
0202 VOL = get_elem_volume(inv_model.fwd_model)';
0203
0204
0205 d_len = size(h_data,1);
0206 delta = 1e-2* mean(h_data);
0207 sig_data = mean(abs( ...
0208 calc_difference_data( h_data, c_data , inv_model.fwd_model ) ...
0209 ));
0210
0211
0212
0213 [img0] = get_images( inv_model, h_data, c_data);
0214
0215 sig_img= VOL*abs(img0) / length(img0);
0216
0217
0218 var_data= 0;
0219 var_img = 0;
0220 for i=1:d_len
0221 this_noise = -ones(d_len, size(c_data,2))/(d_len-1);
0222 this_noise(i,:) = 1;
0223 c_noise = c_data + this_noise;
0224 [imgn] = get_images( inv_model, h_data, c_noise);
0225 if 1
0226 var_data = var_data + mean(sum( ...
0227 calc_difference_data( h_data, c_noise, inv_model.fwd_model ) ...
0228 .^2, 2));
0229
0230 var_img= var_img + (VOL.^2)*sum(imgn.elem_data.^2,2 ) / length(imgn.elem_data);
0231 else
0232
0233 var_data = var_data + var( ...
0234 calc_difference_data( h_data, c_noise, inv_model.fwd_model ) ...
0235 );
0236 var_img= var_img + var( VOL'.*imgn.elem_data );
0237 end
0238 end
0239 var_data = var_data / d_len;
0240 var_img = var_img / d_len;
0241 NF = ( sig_data/ sqrt(var_data) ) / ( sig_img / sqrt(var_img) );
0242
0243 function [NF,SE]= nf_calc_random( rec, vh, vi, N_RUNS);
0244 eidors_cache('boost_priority',-2);
0245
0246 imgr= inv_solve(rec, vh, vi);
0247
0248 if isfield(imgr,'node_data');
0249 img0 = imgr.node_data;
0250 VOL = get_elem_volume(rec.fwd_model, 1);
0251 else
0252 img0 = imgr.elem_data;
0253 VOL = get_elem_volume(rec.fwd_model, 0);
0254 end
0255
0256 sig_ampl = mean( abs( VOL .* img0 )) / ...
0257 mean( abs( calc_difference_data( vh, vi, rec.fwd_model )));
0258
0259
0260 for i=1:N_RUNS
0261 vn= addnoise(vh, vi, 1.0);
0262
0263 imgr= inv_solve(rec, vh, vn);
0264
0265 if isfield(imgr,'node_data'); img0 = imgr.node_data;
0266 else; img0 = imgr.elem_data;
0267 end
0268
0269 noi_imag(i) = std( VOL .* img0 );
0270 noi_sgnl(i) = std( calc_difference_data( vh, vn, rec.fwd_model ));
0271 end
0272
0273 noi_ampl = noi_imag./noi_sgnl;
0274 NF = mean(noi_ampl/sig_ampl);
0275 SE = std(noi_ampl/sig_ampl)/sqrt(N_RUNS);
0276 eidors_msg('NF= %f+/-%f', NF, SE, 1);
0277
0278 eidors_cache('boost_priority',2);
0279
0280 function noise= addnoise( vh, vi, SNR);
0281 if isstruct(vh); vh= vh.meas; end
0282 if isstruct(vi); vi= vi.meas; end
0283 noise = randn(size(vh));
0284 noise = noise*std(vh-vi)/std(noise);
0285 noise = vh + SNR*noise;
0286
0287