0001 function HP = choose_image_SNR(imdl)
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 if ~isfield(imdl.hyperparameter, 'SNR_func')
0030 imdl.hyperparameter.SNR_func = @calc_image_SNR;
0031 end
0032
0033 SnrGoal = imdl.hyperparameter.image_SNR;
0034 assert(SnrGoal > 0, 'SNR is expected to be greater than zero!');
0035
0036 hpInitValue = 1E-1;
0037 try
0038 hpInitValue = imdl.hyperparameter.value;
0039 imdl.hyperparameter = rmfield(imdl.hyperparameter,'value');
0040 end
0041
0042 copt.boost_priority = 3;
0043 copt.fstr = 'choose_image_SNR';
0044 HP = eidors_cache(@HP_for_SNR_search,{SnrGoal,imdl,hpInitValue},copt);
0045
0046
0047
0048 function HP = HP_for_SNR_search(SnrGoal,imdl,hpInitValue)
0049 llv = eidors_msg('log_level');
0050 if llv==3; eidors_msg('log_level',2); end
0051
0052 if true
0053
0054
0055
0056 fms_opts.MaxIter = 15;
0057 fms_opts.TolFun = 0.01 * SnrGoal;
0058 [HpMaxSnr, NegSnrMax] = fminsearch(@(x) -calc_image_SNR(imdl, x), hpInitValue, fms_opts);
0059
0060
0061 assert(SnrGoal <= abs(NegSnrMax), ...
0062 sprintf('Desired SNR (%0.4d) exceeds maximal possible SNR of %0.4d!', SnrGoal, abs(NegSnrMax)));
0063 else
0064
0065 HpMaxSnr = hpInitValue;
0066 end
0067
0068
0069 [hp, x, y] = search1(SnrGoal, imdl, -log10(HpMaxSnr));
0070 eidors_msg('Crossed target value, now refining search in this region...', 2);
0071
0072 dx= hp-linspace(-0.7,0.7,5);
0073 [hp, Snr] = search2(SnrGoal, imdl, dx);
0074
0075 dx= hp-linspace(-0.2,0.2,5);
0076 [hp, Snr] = search2(SnrGoal,imdl, dx);
0077
0078 dx= hp-linspace(-0.1,0.1,5);
0079 [hp, Snr] = search2(SnrGoal,imdl, dx);
0080
0081 dx= hp-linspace(-0.05,0.05,21);
0082 [hp, Snr] = search2(SnrGoal,imdl, dx);
0083
0084
0085
0086
0087 HP= 10^-hp;
0088 assert(HP < HpMaxSnr, 'Something went wrong we''re on the wrong side of the curve!');
0089 eidors_msg('log_level',llv);
0090
0091
0092
0093 function [hp, x, y] = search1(SnrGoal, imdl, hp)
0094 [Snr,SE]=imdl.hyperparameter.SNR_func(imdl, 10^(-hp));
0095 hpInitial = hp;
0096 SnrInitial = Snr;
0097 y = Snr;
0098 x = 10^(-hp);
0099 if Snr > SnrGoal;
0100 dir = 1;
0101 elseif Snr < SnrGoal;
0102 dir = -1;
0103 warning('this should not happen!!!');
0104 else dir = 0; end
0105
0106
0107 while (dir*Snr+3*SE > dir*SnrGoal)
0108 hp= hp+0.5*dir;
0109 [Snr,SE]=imdl.hyperparameter.SNR_func( imdl, 10^(-hp));
0110 y = [y Snr];
0111 x = [x 10^(-hp)];
0112
0113
0114 if Snr < 0
0115
0116
0117 hp = hpInitial;
0118 dir = -dir;
0119 Snr = inf;
0120 eidors_msg('Falling back to initial hp and reversing search direction due to negative SNRs.', 2);
0121 end
0122 end
0123
0124 function [hp, Snr] =search2(SnrGoal, imdl, dx)
0125 hp = [];
0126 it = 0;
0127 Snr = zeros(1,length(dx));
0128 while isempty(hp) && it < 2
0129 it = it+1;
0130
0131 for k=1:length(dx)
0132 Snr(k)=Snr(k)+imdl.hyperparameter.SNR_func( imdl, 10^-dx(k));
0133 end
0134 if 0
0135 log_snr = log10(Snr/it);
0136 p= polyfit( dx, log_snr-log10(SnrGoal), 3);
0137 else
0138 p= polyfit( dx, (Snr/it)-SnrGoal, 3);
0139 end
0140 hp = roots(p);
0141
0142 hp = hp(imag(hp)==0);
0143
0144 hp = hp( hp<max(dx) & hp>min(dx) );
0145
0146 if numel(hp) >1
0147 p2 = p.*(numel(p)-1:-1:0); p2(end) = [];
0148 [jnk, pos] = min(abs(polyval(p2,hp)));
0149 hp = hp(pos);
0150 end
0151
0152 if 0
0153 figure(); subplot(121);
0154 plot(dx, Snr-SnrGoal, ':.')
0155 hold on;
0156 xs = linspace(min(dx), max(dx), 100);
0157 plot(xs, polyval(p, xs), 'r')
0158
0159 subplot(122);
0160 plot(dx, log10(Snr/it)-log10(SnrGoal))
0161 end
0162 end
0163 if isempty(hp)
0164
0165 [jnk,idx] = min(abs((Snr/it)-SnrGoal));
0166
0167 hp = dx(idx);
0168 end