The Flutter Shutter Code Optimizer
 All Files Functions Macros Pages
gain_evaluation.cpp
Go to the documentation of this file.
1 /*gain_evaluation.cpp*/
2 /*
3 * Copyright 2014 IPOL Image Processing On Line http://www.ipol.im/
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
28 #include <math.h>
29 #include "gain_evaluation.h"
30 
31 #ifndef ABS
32 
35 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
36 #endif
37 
38 
39 #ifndef M_PI
40 
44 #define M_PI 3.14159265358979323846
45 #endif
46 
47 #ifndef SQRT_TWOPI
48 
51 #define SQRT_TWOPI 2.506628274631000
52 #endif
53 
57 #define N_RESOLUTION 1000; // for Rieman sum
58 
59 
60 
61 
67 
80 double MSE_snapshot_of_velocity(double velocity, double tilde_deltat)
81 {
82 
83  if (ABS(velocity)>0)
84  {
86  double a=0;
87  double b=M_PI; // a,b integral bounds of (21).
88  // the following is for the Riemann sum.
89  double DELTA_XI=(b-a)/N_RESOLUTION;
90  double xi=0;
91  double tn=0;
92 
93  for(xi = a; xi < b; xi += DELTA_XI)
94  {
95  /* Riemann sum*/
97  tilde_deltat, xi)*DELTA_XI;
98  }
99  return(tn);
100  }
101  else // velocity=0, see remark 4 page 10.
102  {
103  return(M_PI/tilde_deltat);
104  }
105 }
106 
107 
108 
119 double MSE_snapshot_of_velocity_integrand(double velocity,
120  double tilde_deltat, double xi)
121 {
122  double xivdt_2=xi*velocity*tilde_deltat/2;
123  double sinc=1;
124 
125  if (ABS(xivdt_2)>0)
126  {
127  sinc=sin(xivdt_2)/xivdt_2;
128  }
129  // (else) sinc=1 since sinc(0)=1
130  // (see the variable initialization).
131  return(1/(tilde_deltat*sinc*sinc));
132  // this is the integrand in (21).
133 }
134 
135 
141 
158 double MSE_flutter_of_velocity(double* code, int code_length, double velocity,
159  double deltat)
160 {
161 
162  if (ABS(velocity)>0)
163  {
165  double a=0;
166  double b=M_PI; // a,b integral bounds of (21).
167  // the following is for the Riemann sum.
168  double DELTA_XI=(b-a)/N_RESOLUTION;
169  double xi=0;
170  double tn=0;
171 
172  for(xi = a; xi < b; xi += DELTA_XI)
173  {
174  /* Riemann sum*/
175  tn += MSE_flutter_of_velocity_integrand(code, code_length, velocity,
176  deltat, xi)*DELTA_XI;
177  }
178  return(tn);
179  }
180  else // velocity=0, see remark 4 page 10.
181  {
182  return(M_PI*MSE_flutter_of_velocity_integrand(code, code_length, 0,
183  deltat, 0));
184  }
185 }
186 
200 double MSE_flutter_of_velocity_integrand(double* code, int code_length,
201  double velocity, double deltat, double xi)
202 {
204  double modulus_hat_alpha_of_vxi=abs_hat_alpha(code, code_length,
205  xi*velocity,deltat);
206  double l2_norm_code_squared=0;
207 
209  for (int k=0; k<code_length; k++)
210  {
211  l2_norm_code_squared=l2_norm_code_squared+ code[k]*code[k]*deltat;
212  }
213 
214  return(l2_norm_code_squared/(modulus_hat_alpha_of_vxi*
215  modulus_hat_alpha_of_vxi));
216 }
217 
218 
234 double abs_hat_alpha(double* code, int code_length, double xi, double deltat)
235 {
237  //initialization
238  double re_abs_hat_alpha=0; //real part
239  double im_abs_hat_alpha=0; //imaginary part
240  //Main loop
241  for (int k=0; k<code_length; k++)
242  {
243  im_abs_hat_alpha =im_abs_hat_alpha+code[k]*sin(-xi*deltat*(k+0.5));
244  re_abs_hat_alpha =re_abs_hat_alpha+code[k]*cos(-xi*deltat*(k+0.5));
245  }
246 
247  if (ABS(xi)>0) //avoiding 0/0
248  {
249  im_abs_hat_alpha =im_abs_hat_alpha*sin(xi*deltat/2)
250  /(xi*deltat/2);//ELSE =1;
251  re_abs_hat_alpha =re_abs_hat_alpha*sin(xi*deltat/2)
252  /(xi*deltat/2); //ELSE =1;
253  }
254 
255  return(deltat*pow(im_abs_hat_alpha*im_abs_hat_alpha+
256  re_abs_hat_alpha*re_abs_hat_alpha,0.5));
257 }
258 
259 
260 
265 
284 double gain_in_terms_of_RMSE_at_velocity_v(double* code, int code_length,
285  double tilde_deltat, double velocity, double deltat)
286 {
287  return(pow(MSE_snapshot_of_velocity(velocity, tilde_deltat)/
288  MSE_flutter_of_velocity(code, code_length, velocity,
289  deltat),0.5));// This is equation (23).
290 }
291 
292 
297 
310 double probability_density(double velocity, int flag_motion_model,
311  double motion_model_parameter)
312 {
313  if (flag_motion_model==0) //Gaussian
314  {
315  // Recall that for the Gaussian case motion_model_parameter is \sigma
316  return((1/(motion_model_parameter*SQRT_TWOPI)
317  *exp(-velocity*velocity/
318  (2*motion_model_parameter*motion_model_parameter))));
319  }
320  else // Uniform
321  // for the Uniform motion model motion_model_parameter is v_{max}
322  {
323  return(1/(2*motion_model_parameter)) ;
324  }
325 
326  return(0);
327 }
328 
329 
353 void average_gain_in_terms_of_RMSE(double* code, int code_length,
354  double tilde_deltat_star,
355  int flag_motion_model,
356  double motion_model_parameter,double deltat,
357  int num_plot_points,
358  double *G_of_v,
359  double *average_gain_mu)
360 {
362  // Recall that for the Gaussian case motion_model_parameter is \sigma
363  // for the Uniform motion model motion_model_parameter is v_{max}
364  double velocity_max=motion_model_parameter;
365  if (flag_motion_model==0) velocity_max=4*motion_model_parameter;
366  //at this point velocity_max contains v_{max} for both motion models.
367  average_gain_mu[0]=0;
368  int i=0;
369  double sum_probabilities=0;
370  double probability_of_v=0;
371 
373 
374  if (flag_motion_model==1) //uniform motion model
375  {
376  probability_of_v=probability_density(0, 1,
377  motion_model_parameter);
378  for (double velocity=-velocity_max; velocity<velocity_max;
379  velocity=velocity+2*velocity_max/num_plot_points)
380  {
382  code_length, tilde_deltat_star, velocity,
383  deltat);
384  // G_of_v[0] is the gain at v=-v_{max}, etc.
385  sum_probabilities=sum_probabilities+probability_of_v;
386  // for normalization so that \sum probability_of_v=1.
387  average_gain_mu[0]=average_gain_mu[0]// 0 in init
388  +G_of_v[i]
389  *probability_of_v;
390  i++;
391  }
392  }
393  else // Gaussian motion model
394  {
395  for (double velocity=-velocity_max; velocity<velocity_max;
396  velocity=velocity+2*velocity_max/num_plot_points)
397  {
398  probability_of_v=probability_density(velocity, 0,
399  motion_model_parameter);
401  code_length, tilde_deltat_star, velocity,
402  deltat);
403  // G_of_v[0] is the gain at v=-v_{max}, etc.
404  sum_probabilities=sum_probabilities+probability_of_v;
405  // for normalization so that \sum probability_of_v=1.
406  average_gain_mu[0]=average_gain_mu[0]// 0 in init
407  +G_of_v[i]
408  *probability_of_v;
409  i++;
410  }
411  }
412 
413  average_gain_mu[0]=average_gain_mu[0]/sum_probabilities;
414 // to ensure that the mass is = 1.
415 }
416 
417 
422 
446 void std_dev_gain_in_terms_of_RMSE(int flag_motion_model,
447  double motion_model_parameter,
448  int num_plot_points,
449  double *G_of_v,
450  double *average_gain_mu,
451  double *std_dev_gain_sigma)
452 {
453 
455  // Recall that for the Gaussian case motion_model_parameter is \sigma
456  // for the Uniform motion model motion_model_parameter is v_{max}
457  double velocity_max=motion_model_parameter;
458  if (flag_motion_model==0) velocity_max=4*motion_model_parameter;
459  //at this point velocity_max contains v_{max} for both motion models.
460  std_dev_gain_sigma[0]=0;
461  int i=0;
462  double sum_probabilities=0;
463  double probability_of_v=0;
464 
466 
467  if (flag_motion_model==1) //uniform motion model
468  {
469  probability_of_v=1/(2*velocity_max) ;
470  for (double velocity=-velocity_max; velocity<velocity_max;
471  velocity=velocity+2*velocity_max/num_plot_points)
472  {
473  // G_of_v[0] is the gain at v=-v_{max}, etc.
474  sum_probabilities=sum_probabilities+probability_of_v;
475  // for normalization so that \sum probability_of_v=1.
476  std_dev_gain_sigma[0]=std_dev_gain_sigma[0]+
477  (G_of_v[i]-
478  average_gain_mu[0])*
479  (G_of_v[i]-
480  average_gain_mu[0])*
481  probability_of_v;
482  i++;
483  }
484  }
485  else // Gaussian motion model
486  {
487  for (double velocity=-velocity_max; velocity<velocity_max;
488  velocity=velocity+2*velocity_max/num_plot_points)
489  {
490  probability_of_v=probability_density(velocity, 0,
491  motion_model_parameter);
492  // G_of_v[0] is the gain at v=-v_{max}, etc.
493  sum_probabilities=sum_probabilities+probability_of_v;
494  // for normalization so that \sum probability_of_v=1.
495  std_dev_gain_sigma[0]=std_dev_gain_sigma[0]+
496  (G_of_v[i]-
497  average_gain_mu[0])*
498  (G_of_v[i]-
499  average_gain_mu[0])*
500  probability_of_v;
501  i++;
502  }
503  }
504  std_dev_gain_sigma[0]=pow(std_dev_gain_sigma[0]/
505  sum_probabilities,.5);
506 }
void average_gain_in_terms_of_RMSE(double *code, int code_length, double tilde_deltat_star, int flag_motion_model, double motion_model_parameter, double deltat, int num_plot_points, double *G_of_v, double *average_gain_mu)
This function implements equation (24): := G(v) (v) dv.
#define N_RESOLUTION
double MSE_snapshot_of_velocity_integrand(double velocity, double tilde_deltat, double xi)
This function computes the integrand of equation (21): {1}{T {sinc}^2( { v T}{2 })}.
double probability_density(double velocity, int flag_motion_model, double motion_model_parameter)
Given a velocity velocity, the motion model and its parameters the function computes the probability...
double gain_in_terms_of_RMSE_at_velocity_v(double *code, int code_length, double tilde_deltat, double velocity, double deltat)
This function implements equation (23): G(v)&={ {{0}^{} {1} {T^* {sinc}^2( { v T^*}{2 })}d} { {0}^{} ...
double MSE_flutter_of_velocity(double *code, int code_length, double velocity, double deltat)
This function computes the MSE of flutter shutter for a given velocity. This is equation (22) up to a...
#define SQRT_TWOPI
#define ABS(x)
#define M_PI
double abs_hat_alpha(double *code, int code_length, double xi, double deltat)
Given a code compute the modulus of the Fourier transform of the Flutter-Shutter function, see equation (2): ()= t {sinc}({ t}{2}) e^{-{i t}{2}} {k=0}^{L-1} e^{-ik t}.
double MSE_flutter_of_velocity_integrand(double *code, int code_length, double velocity, double deltat, double xi)
This function computes the integrand of equation (21): {| |^2_{L^2()} |u|_{L^1()}}{| ( v)|^2}d...
void std_dev_gain_in_terms_of_RMSE(int flag_motion_model, double motion_model_parameter, int num_plot_points, double *G_of_v, double *average_gain_mu, double *std_dev_gain_sigma)
This function implements equation (25): :={ |G(v)- G(u) (u) du|^2 (v) dv}.
double MSE_snapshot_of_velocity(double velocity, double tilde_deltat)
This function computes the MSE of a snapshot for a given velocity. This is equation (21) up to a 1 ...