The Flutter Shutter Code Optimizer
|
00001 /*gain_evaluation.cpp*/ 00002 /* 00003 * Copyright 2014 IPOL Image Processing On Line http://www.ipol.im/ 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00029 #include <math.h> 00030 #include "code_comparison.h" 00031 00032 #ifndef ABS 00033 00036 #define ABS(x) (((x) > 0) ? (x) : (-(x))) 00037 #endif 00038 00039 00040 #ifndef M_PI 00041 00045 #define M_PI 3.14159265358979323846 00046 #endif 00047 00048 #ifndef SQRT_TWOPI 00049 00052 #define SQRT_TWOPI 2.506628274631000 00053 #endif 00054 00058 #define N_RESOLUTION 1000; // for Rieman sum 00059 00060 00061 00062 00068 00079 double MSE_snapshot_of_velocity(double velocity,double tilde_deltat) 00080 { 00081 00082 if (ABS(velocity)>0) 00083 { 00085 double a=0; 00086 double b=M_PI; // a,b integral bounds of (20). 00087 // the following is for the Riemann sum. 00088 double DELTA_XI=(b-a)/N_RESOLUTION; 00089 double xi=0; 00090 double tn=0; 00091 00092 for(xi = a; xi < b; xi += DELTA_XI) 00093 { 00094 /* Riemann sum*/ 00095 tn += MSE_snapshot_of_velocity_integrand(velocity, 00096 tilde_deltat, xi)*DELTA_XI; 00097 } 00098 return(tn); 00099 } 00100 else // velocity=0, see remark 3 page 10. 00101 { 00102 return(M_PI/tilde_deltat); 00103 } 00104 } 00105 00106 00107 00117 double MSE_snapshot_of_velocity_integrand(double velocity, 00118 double tilde_deltat, double xi) 00119 { 00120 double xivelocitydt_2=xi*velocity*tilde_deltat/2; 00121 double hat_snapshot_xi=1; 00122 00123 if (ABS(xivelocitydt_2)>0) 00124 { 00125 hat_snapshot_xi=sin(xivelocitydt_2)/xivelocitydt_2; 00126 } 00127 // (else) hat_snapshot_xi=1 since sinc(0)=1. 00128 return(1/(tilde_deltat*hat_snapshot_xi*hat_snapshot_xi)); 00129 // this is the integrand in (20). 00130 } 00131 00132 00138 00153 double MSE_flutter_of_velocity(double* code, int code_length, double velocity, 00154 double deltat) 00155 { 00156 00157 if (ABS(velocity)>0) 00158 { 00160 double a=0; 00161 double b=M_PI; // a,b integral bounds of (21). 00162 // the following is for the Riemann sum. 00163 double DELTA_XI=(b-a)/N_RESOLUTION; 00164 double xi=0; 00165 double tn=0; 00166 00167 for(xi = a; xi < b; xi += DELTA_XI) 00168 { 00169 /* Riemann sum*/ 00170 tn += MSE_flutter_of_velocity_integrand(code, code_length, velocity, 00171 deltat, xi)*DELTA_XI; 00172 } 00173 return(tn); 00174 } 00175 else // velocity=0, see remark 3 page 10. 00176 { 00177 return(M_PI*MSE_flutter_of_velocity_integrand(code, code_length, 0, 00178 deltat, 0)); 00179 } 00180 } 00181 00194 double MSE_flutter_of_velocity_integrand(double* code, int code_length, 00195 double velocity, double deltat, double xi) 00196 { 00198 double modulus_hat_alpha_of_vxi=abs_hat_alpha(code, code_length, 00199 xi*velocity,deltat); 00200 double l2_norm_code_squared=0; 00201 00203 for (int k=0; k<code_length; k++) 00204 { 00205 l2_norm_code_squared=l2_norm_code_squared+ code[k]*code[k]*deltat; 00206 } 00207 00208 return(l2_norm_code_squared/(modulus_hat_alpha_of_vxi* 00209 modulus_hat_alpha_of_vxi)); 00210 } 00211 00212 00225 double abs_hat_alpha(double* code, int code_length, double xi, double deltat) 00226 { 00228 //initialization 00229 double re_abs_hat_alpha=0; //real part 00230 double im_abs_hat_alpha=0; //imaginary part 00231 //Main loop 00232 for (int k=0; k<code_length; k++) 00233 { 00234 im_abs_hat_alpha =im_abs_hat_alpha+code[k]*sin(-xi*deltat*(k+0.5)); 00235 re_abs_hat_alpha =re_abs_hat_alpha+code[k]*cos(-xi*deltat*(k+0.5)); 00236 } 00237 00238 if (ABS(xi)>0) //avoiding 0/0 00239 { 00240 im_abs_hat_alpha =im_abs_hat_alpha*sin(xi*deltat/2) 00241 /(xi*deltat/2);//ELSE =1; 00242 re_abs_hat_alpha =re_abs_hat_alpha*sin(xi*deltat/2) 00243 /(xi*deltat/2); //ELSE =1; 00244 } 00245 00246 return(deltat*pow(im_abs_hat_alpha*im_abs_hat_alpha+ 00247 re_abs_hat_alpha*re_abs_hat_alpha,0.5)); 00248 } 00249 00250 00251 00256 00270 double gain_in_terms_of_RMSE_at_velocity_v(double* code, int code_length, 00271 double tilde_deltat, double velocity, double deltat) 00272 { 00273 return(pow(MSE_snapshot_of_velocity(velocity, tilde_deltat)/ 00274 MSE_flutter_of_velocity(code, code_length, velocity, 00275 deltat),0.5));// This is equation (22). 00276 } 00277 00278 00283 00297 double probability_density(double velocity, int flag_motion_model, 00298 double motion_model_parameter) 00299 { 00300 if (flag_motion_model==0) //Gaussian 00301 { 00302 // Recall that for the Gaussian case motion_model_parameter is \sigma 00303 return((1/(motion_model_parameter*SQRT_TWOPI) 00304 *exp(-velocity*velocity/ 00305 (2*motion_model_parameter*motion_model_parameter)))); 00306 } 00307 else // Uniform 00308 // for the Uniform motion model motion_model_parameter is v_{max} 00309 { 00310 return(1/(2*motion_model_parameter)) ; 00311 } 00312 00313 return(0); 00314 } 00315 00316 00340 void average_gain_in_terms_of_RMSE(double* code, int code_length, 00341 double tilde_deltat_star, 00342 int flag_motion_model, 00343 double motion_model_parameter,double deltat, 00344 int num_plot_points, 00345 double *gain_of_v_equation_22, 00346 double *average_gain_equation_23) 00347 { 00349 // Recall that for the Gaussian case motion_model_parameter is \sigma 00350 // for the Uniform motion model motion_model_parameter is v_{max} 00351 double velocity_max=motion_model_parameter; 00352 if (flag_motion_model==0) velocity_max=4*motion_model_parameter; 00353 //at this point velocity_max contains v_{max} for both motion models. 00354 average_gain_equation_23[0]=0; 00355 int i=0; 00356 double sum_probabilities=0; 00357 double probability_of_v=0; 00358 00360 00361 if (flag_motion_model==1) //uniform motion model 00362 { 00363 probability_of_v=1/(2*velocity_max) ; 00364 for (double velocity=-velocity_max; velocity<velocity_max; 00365 velocity=velocity+2*velocity_max/num_plot_points) 00366 { 00367 gain_of_v_equation_22[i]=gain_in_terms_of_RMSE_at_velocity_v(code, 00368 code_length, tilde_deltat_star, velocity, 00369 deltat); 00370 // gain_of_v_equation_22[0] is the gain at v=-v_{max}, etc. 00371 sum_probabilities=sum_probabilities+probability_of_v; 00372 // for normalization so that \sum probability_of_v=1. 00373 average_gain_equation_23[0]=average_gain_equation_23[0]// 0 in init 00374 +gain_of_v_equation_22[i] 00375 *probability_of_v; 00376 i++; 00377 } 00378 } 00379 else // Gaussian motion model 00380 { 00381 for (double velocity=-velocity_max; velocity<velocity_max; 00382 velocity=velocity+2*velocity_max/num_plot_points) 00383 { 00384 probability_of_v=probability_density(velocity, 0, 00385 motion_model_parameter); 00386 gain_of_v_equation_22[i]=gain_in_terms_of_RMSE_at_velocity_v(code, 00387 code_length, tilde_deltat_star, velocity, 00388 deltat); 00389 // gain_of_v_equation_22[0] is the gain at v=-v_{max}, etc. 00390 sum_probabilities=sum_probabilities+probability_of_v; 00391 // for normalization so that \sum probability_of_v=1. 00392 average_gain_equation_23[0]=average_gain_equation_23[0]// 0 in init 00393 +gain_of_v_equation_22[i] 00394 *probability_of_v; 00395 i++; 00396 } 00397 } 00398 00399 average_gain_equation_23[0]=average_gain_equation_23[0]/sum_probabilities; 00400 // to ensure that the mass is = 1. 00401 } 00402 00403 00408 00431 void std_dev_gain_in_terms_of_RMSE(int flag_motion_model, 00432 double motion_model_parameter, 00433 int num_plot_points, 00434 double *gain_of_v_equation_22, 00435 double *average_gain_equation_23, 00436 double *std_dev_gain_equation_24) 00437 { 00438 00440 // Recall that for the Gaussian case motion_model_parameter is \sigma 00441 // for the Uniform motion model motion_model_parameter is v_{max} 00442 double velocity_max=motion_model_parameter; 00443 if (flag_motion_model==0) velocity_max=4*motion_model_parameter; 00444 //at this point velocity_max contains v_{max} for both motion models. 00445 std_dev_gain_equation_24[0]=0; 00446 int i=0; 00447 double sum_probabilities=0; 00448 double probability_of_v=0; 00449 00451 00452 if (flag_motion_model==1) //uniform motion model 00453 { 00454 probability_of_v=1/(2*velocity_max) ; 00455 for (double velocity=-velocity_max; velocity<velocity_max; 00456 velocity=velocity+2*velocity_max/num_plot_points) 00457 { 00458 // gain_of_v_equation_22[0] is the gain at v=-v_{max}, etc. 00459 sum_probabilities=sum_probabilities+probability_of_v; 00460 // for normalization so that \sum probability_of_v=1. 00461 std_dev_gain_equation_24[0]=std_dev_gain_equation_24[0]+ 00462 (gain_of_v_equation_22[i]- 00463 average_gain_equation_23[0])* 00464 (gain_of_v_equation_22[i]- 00465 average_gain_equation_23[0])* 00466 probability_of_v; 00467 i++; 00468 } 00469 } 00470 else // Gaussian motion model 00471 { 00472 for (double velocity=-velocity_max; velocity<velocity_max; 00473 velocity=velocity+2*velocity_max/num_plot_points) 00474 { 00475 probability_of_v=probability_density(velocity, 0, 00476 motion_model_parameter); 00477 // gain_of_v_equation_22[0] is the gain at v=-v_{max}, etc. 00478 sum_probabilities=sum_probabilities+probability_of_v; 00479 // for normalization so that \sum probability_of_v=1. 00480 std_dev_gain_equation_24[0]=std_dev_gain_equation_24[0]+ 00481 (gain_of_v_equation_22[i]- 00482 average_gain_equation_23[0])* 00483 (gain_of_v_equation_22[i]- 00484 average_gain_equation_23[0])* 00485 probability_of_v; 00486 i++; 00487 } 00488 } 00489 std_dev_gain_equation_24[0]=pow(std_dev_gain_equation_24[0]/ 00490 sum_probabilities,.5); 00491 }