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 /* } */
|
|