contrib/rpl/rrel/rrel_muse_table.cxx
Go to the documentation of this file.
00001 // This is rpl/rrel/rrel_muse_table.cxx
00002 #include "rrel_muse_table.h"
00003 #include <rrel/rrel_misc.h>
00004 #include <vnl/vnl_math.h>
00005 
00006 #include <vcl_cmath.h>
00007 #include <vcl_cassert.h>
00008 
00009 bool operator< ( rrel_muse_key_type const& left_t, rrel_muse_key_type const& right_t )
00010 {
00011   return left_t.n_ < right_t.n_
00012     || ( left_t.n_ == right_t.n_ && left_t.k_ < right_t.k_ );
00013 }
00014 
00015 double
00016 rrel_muse_table::expected_kth( unsigned int k, unsigned int n )
00017 {
00018   assert( 0<k && k<= n );
00019   rrel_muse_key_type key(k,n);
00020   rrel_muse_table_entry& entry = table_[key];
00021   if ( ! entry . initialized_ )
00022     calculate_all( k, n, entry );
00023   return entry . expected_;
00024 }
00025 
00026 double
00027 rrel_muse_table::standard_dev_kth( unsigned int k, unsigned int n )
00028 {
00029   assert( 0<k && k<=n );
00030   rrel_muse_key_type key(k,n);
00031   rrel_muse_table_entry& entry = table_[key];
00032   if ( ! entry . initialized_ )
00033     calculate_all( k, n, entry );
00034   return entry . standard_dev_;
00035 }
00036 
00037 double
00038 rrel_muse_table::muset_divisor( unsigned int k, unsigned int n )
00039 {
00040   assert( 0<k && k<= n );
00041   rrel_muse_key_type key(k,n);
00042   rrel_muse_table_entry& entry = table_[key];
00043   if ( ! entry . initialized_ )
00044     calculate_all( k, n, entry );
00045   return entry . muse_t_divisor_;
00046 }
00047 
00048 
00049 double
00050 rrel_muse_table::muset_sq_divisor( unsigned int k, unsigned int n )
00051 {
00052   assert( 0<k && k<= n );
00053   rrel_muse_key_type key(k,n);
00054   rrel_muse_table_entry& entry = table_[key];
00055   if ( ! entry . initialized_ )
00056     calculate_all( k, n, entry );
00057   return entry . muse_t_sq_divisor_;
00058 }
00059 
00060 void
00061 rrel_muse_table::calculate_all( unsigned int k, unsigned int n,
00062                                 rrel_muse_table_entry & entry )
00063 {
00064   entry . initialized_ = true;
00065   entry . expected_ = calculate_expected( k, n );
00066   entry . standard_dev_ = calculate_standard_dev( k, n, entry . expected_ );
00067   entry . muse_t_divisor_ = calculate_divisor( k, n, entry . expected_ );
00068   entry . muse_t_sq_divisor_ = calculate_sq_divisor( k, n, entry . expected_ );
00069 }
00070 
00071 double
00072 rrel_muse_table::calculate_expected( unsigned int k, unsigned int n ) const
00073 {
00074   return rrel_misc_gaussian_cdf_inv(0.5*(1.0+((double)k / (double)(n+1))));
00075 }
00076 
00077 
00078 double
00079 rrel_muse_table::calculate_standard_dev( unsigned int k, unsigned int n,
00080                                          double expected_kth ) const
00081 {
00082   double pk, qk, Qk, pQk, Qk_prime, Qk_dprime, Qk_tprime, vrk;
00083 
00084   pk = (double) k / (double) (n+1); // might want alpha beta correction
00085   qk = 1.0 - pk;
00086 
00087   // calculate_ the inverse cdf (might want to an alpha-beta correction)
00088   Qk = expected_kth;  // ak(k, N);   // inverse cdf of absolute residuals
00089 
00090   // density of absolute residual evaluated at Qk
00091   pQk = vcl_exp( -0.5 * Qk*Qk) * vcl_sqrt(2.0 / vnl_math::pi);
00092 
00093   // first derivative of Qk
00094   Qk_prime = 1.0/pQk;
00095 
00096   /*
00097   //  Low order approximation
00098   vrk = (pk*qk/(double)(n+2)) * Qk_prime*Qk_prime;
00099   */
00100 
00101   // second derivative of Qk
00102   Qk_dprime = Qk/(pQk*pQk);
00103 
00104   // third derivative of Qk
00105   Qk_tprime = ( 1.0 + 2.0 * Qk*Qk ) / (pQk*pQk*pQk);
00106 
00107   //  Higher order approximation
00108   vrk = (pk*qk/(double)(n+2)) * Qk_prime*Qk_prime
00109         + (pk*qk/((double)((n+2)*(n+2)))) * ( 2.0*(qk - pk)*Qk_prime*Qk_dprime
00110         + pk*qk*(Qk_prime*Qk_tprime + 0.5*Qk_dprime*Qk_dprime));
00111 
00112   return vcl_sqrt(vrk);
00113 }
00114 
00115 
00116 double
00117 rrel_muse_table::calculate_divisor( unsigned int /* k */, unsigned int n,
00118                                     double expected_kth ) const
00119 {
00120   return (n+1)*vcl_sqrt(2/vnl_math::pi)*(1.0-vcl_exp(-vnl_math_sqr(expected_kth)/2.0));
00121 }
00122 
00123 double
00124 rrel_muse_table::calculate_sq_divisor( unsigned int k, unsigned int n,
00125                                        double expected_kth ) const
00126 {
00127   return k - (n+1) * expected_kth * vcl_sqrt(2/vnl_math::pi)
00128     * vcl_exp(-vnl_math_sqr(expected_kth)/2.0);
00129 }
00130