src/source_func.c

Go to the documentation of this file.
00001 /*
00002    libit - Library for basic source and channel coding functions
00003    Copyright (C) 2005-2005 Vivien Chappelier, Herve Jegou
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library 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 GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 /*
00021   Various source functions
00022   Copyright (C) 2005 Herve Jegou
00023 */
00024 
00025 
00026 #include <math.h>
00027 #include <it/source_func.h>
00028 #include <it/math.h>
00029 #include <it/io.h>
00030 
00031 /*--------------------------------------------------------------------*/
00032 /* Return the stationnary entropy of a symbol distribution pdf */
00033 double entropy (vec pdf)
00034 {
00035   idx_t i;
00036   double H = 0.0;
00037 
00038   for (i = 0; i < vec_length (pdf); i++)
00039     if (pdf[i] > 0)
00040       H -= pdf[i] * log (pdf[i]);
00041 
00042   return H / log (2.0);
00043 }
00044 
00045 
00046 /*--------------------------------------------------------------------*/
00047 double entropy_bin (double p)
00048 {
00049   if (p <= 0 || p > 1)
00050     return 0;
00051   else
00052     return -p * log2 (p) + (p - 1) * log2 (1 - p);
00053 }
00054 
00055 /*--------------------------------------------------------------------*/
00056 double source_expectation (vec pdf, vec symbols)
00057 {
00058   assert (vec_length (symbols) == vec_length (pdf));
00059   return vec_inner_product (symbols, pdf);
00060 }
00061 
00062 
00063 
00064 /*--------------------------------------------------------------------*/
00065 double source_variance (vec pdf, vec symbols)
00066 {
00067   double v;
00068   idx_t i;
00069   double e = source_expectation (symbols, pdf);
00070   assert (is_valid_pdf (pdf, 1e-6));
00071 
00072   v = 0;
00073   for (i = 0; i < vec_length (symbols); i++)
00074     v += pdf[i] * (symbols[i] - e) * (symbols[i] - e);
00075 
00076   return v;
00077 }
00078 
00079 /*-----------------------------------------------------------------------*/
00080 double entropy_markov (mat pt)
00081 {
00082   idx_t omega = mat_width (pt), s, i;
00083   double entropy = 0;
00084 
00085   /* Compute the stationnary probability law */
00086   vec  pdf = markov_marg_pdf (pt);
00087   it_assert (is_valid_markov_matrix (pt, IT_EPSILON),
00088        "Matrix does not define a valid probability transition matrix");
00089 
00090   for (s = 0; s < omega; s++)
00091     for (i = 0; i < omega; i++)
00092       if (pt[i][s] > 0)
00093   entropy -= pdf[s] * pt[i][s] * log (pt[i][s]);
00094 
00095   vec_delete (pdf);
00096   return (entropy / log (2.0));
00097 }
00098 
00099 
00100 
00101 /*-----------------------------------------------------------------------
00102   !!!TODO: use a SVD instead ! (Single value decomposition)             */
00103 vec markov_marg_pdf (mat pt)
00104 {
00105   int  i;
00106   mat  Mpow = mat_clone (pt), Mtmp;
00107   vec  pdf;
00108 
00109   if (mat_height (pt) != mat_width (pt)) {
00110     it_error ("Numbers of columns and rows don't match, return void vector");
00111     return vec_null;
00112   }
00113 
00114   /* Process the power of the matrix */
00115   for (i = 0; i < 7; i++) {
00116     Mtmp = mat_new_mul (Mpow, Mpow);
00117     mat_delete (Mpow);
00118     Mpow = Mtmp;
00119   }
00120 
00121   pdf = mat_rows_sum (Mpow);
00122   mat_delete (Mpow);
00123   vec_normalize (pdf, 1);
00124   return (pdf);
00125 }
00126 
00127 
00128 /*-----------------------------------------------------------------------
00129  * Return the histogram of the realization SN
00130  * The source is assumed to be an index source that takes its value
00131  * between 0 and omega-1
00132  */
00133 ivec histogram (int omega, ivec S)
00134 {
00135   idx_t t;
00136   ivec histo = ivec_new_zeros (omega);
00137 
00138   for (t = 0; t < ivec_length (S); t++)
00139     if (S[t] < omega)
00140       histo[S[t]]++;
00141 
00142   return histo;
00143 }
00144 
00145 
00146 /*-----------------------------------------------------------------------
00147    Return the histogram of the realization SN normalized to sum to 1
00148    The source is assumed to be an index source that takes its value
00149    between 0 and omega-1
00150  */
00151 vec histogram_normalized (int omega, ivec S)
00152 {
00153   idx_t t;
00154   double delta = 1.0 / ivec_length (S);
00155   vec  histo = vec_new_zeros (omega);
00156 
00157   for (t = 0; t < ivec_length (S); t++)
00158     if (S[t] < omega)
00159       histo[S[t]] += delta;
00160 
00161   return histo;
00162 }
00163 
00164 
00165 /*-----------------------------------------------------------------------*/
00166 imat histogram_cond (int omega, ivec S)
00167 {
00168   imat histo2D = imat_new_zeros (omega, omega);
00169   idx_t t;
00170 
00171   for (t = 1; t < ivec_length (S); t++)
00172     histo2D[S[t]][S[t - 1]]++;
00173 
00174   return histo2D;
00175 }
00176 
00177 
00178 /*----------------------------------------------------------------------*/
00179 int is_valid_pdf (vec pdf, double tol)
00180 {
00181   assert (pdf);
00182   return fabs (1.0 - vec_sum (pdf)) < tol;
00183 }
00184 
00185 
00186 /*-----------------------------------------------------------------------
00187  Return true if the input matrix is a conditionnal probability density function, 
00188  false otherwise */
00189 int is_valid_markov_matrix (mat pt, double tol)
00190 {
00191   idx_t j;
00192   assert (pt);
00193   for (j = 0; j < mat_width (pt); j++)
00194     if (fabs (1.0 - mat_col_sum (pt, j)) < tol)
00195       return 0;
00196   return 1;
00197 }
00198 
00199 /*-----------------------------------------------------------------------
00200  * Convert a source on an alphabet A to a source on the product alphabet A^d
00201  */
00202 /* ivec to_product_alphabet( ivec S, int cardA, int d ) */
00203 /* { */
00204 /*   int NS = S.length(); */
00205 /*   it_assert( NS % d == 0, "Conversion to the product alphabet A^d requires the length of the input vector to be a multiple of d." ); */
00206 
00207 /*   int NP = S.length() / d; */
00208 /*   ivec P( NP ); */
00209 /*   P.zeros(); */
00210 
00211 /*   // is and ip are respectively point in S and P */
00212 /*   // c is the symbol with a product symbol */
00213 /*   int is, ip = -1, c; */
00214 /*   for( is = 0 ; is < NS ; is++ ) */
00215 /*     { */
00216 /*       c = is % d; */
00217 /*       if( c == 0 ) */
00218 /*  ip++; */
00219 
00220 /*       P( ip ) = P( ip ) * cardA + S[ is ]; */
00221 /*     } */
00222 
00223 /*   return P; */
00224 /* } */
00225 
00226 
00227 /* //----------------------------------------------------------------------- */
00228 /* // */
00229 /* ivec to_scalar_alphabet( ivec P, int cardA, int d ) */
00230 /* { */
00231 /*   int NP = P.length(); */
00232 /*   int NS = NP * d; */
00233 
00234 /*   ivec S( NS ); */
00235 
00236 /*   int is = 0, ip, c, cwd; */
00237 /*   for( ip = 0 ; ip < NP ; ip++ ) */
00238 /*     { */
00239 /*       cwd = P[ ip ]; */
00240 /*       for( c = d - 1 ; c >= 0 ; c-- ) */
00241 /*  { */
00242 /*    S[ is + c ] = cwd % cardA; */
00243 /*    cwd /= cardA; */
00244 /*  } */
00245 /*       is += d; */
00246 /*     } */
00247 
00248 /*   return S; */
00249 /* } */
00250 
00251 /* //----------------------------------------------------------------------- */
00252 /* // Return the stationnary transition probabilities of the product alphabet,  */
00253 /* //  assuming a Markovian source */
00254 /* vec alphabet_prod_pdf( mat pt, int d ) */
00255 /* { */
00256 /*   it_assert( pt.rows() == pt.cols(), "Matrix of probability is not square" ); */
00257 
00258 /*   int n = pt.rows(); */
00259 /*   int prod_n = (int) round( pow( n, d ) ); */
00260 
00261 /*   vec prod_pdf( prod_n ); */
00262 /*   prod_pdf.ones(); */
00263 /*   vec pdf = marg_pdf( pt );   // The marginal law for the scalar alphabet */
00264 
00265 /*   // cwd denotes a codeword of the product space  */
00266 /*   int cwd_tmp, s, last_s, i, f; */
00267 /*   double p; */
00268 /*   for( int cwd = 0 ; cwd < prod_n ; cwd++ ) */
00269 /*     { */
00270 /*       last_s = -1; */
00271 /*       cwd_tmp = cwd; */
00272 /*       f = prod_n / n; */
00273 
00274 /*       // i indexes the dimension */
00275 /*       for( i = 0 ; i < d ; i++ ) */
00276 /*  { */
00277 /*    s = cwd_tmp / f; */
00278 /*    cwd_tmp %= f; */
00279 /*    f /= n; */
00280 
00281 /*    // First symbol : no knowledge of past realizations */
00282 /*    if( last_s == -1 ) */
00283 /*      p = pdf( s ); */
00284 
00285 /*    // Use previous symbol for the context */
00286 /*    else */
00287 /*      p = pt( s, last_s ); */
00288 
00289 /*    prod_pdf( cwd ) *= p; */
00290 /*    last_s = s; */
00291 /*  } */
00292 
00293 /*     } */
00294 /*   return prod_pdf; */
00295 /* } */

Hosted by
Copyright (C) 2005-2006 Hervé Jégou
Vivien Chappelier
Francois Cayre
libit logo courtesy of Jonathan Delhumeau