examples/test_quantizer/test_quantizer.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 /*
00003    libit - Library for basic source and channel coding functions
00004    Copyright (C) 2005-2005 Vivien Chappelier, Herve Jegou
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public
00017    License along with this library; if not, write to the Free
00018    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 /*------------------------------------------------------------*/
00022 /** @file test_quantizer.c Test program for quantizer         */
00023 /*------------------------------------------------------------*/
00024 
00025 #include <it/types.h>
00026 #include <it/io.h>
00027 #include <it/vec.h>
00028 #include <it/distance.h>
00029 #include <it/quantizer.h>
00030 #include <it/random.h>
00031 #include <it/source.h>
00032 #include <it/source_func.h>
00033 #include <it/math.h>
00034 
00035 it_function_args (gaussian_pdf)
00036 {
00037   double sigma;
00038 };
00039 
00040 it_function (gaussian_pdf)
00041 {
00042   double sigma = it_this->sigma;  /* standard deviation */
00043 
00044   return (1. / (sqrt (2. * M_PI) * sigma) *
00045     exp (-x * x / (2. * sigma * sigma)));
00046 }
00047 
00048 
00049 it_function_args (laplacian_pdf)
00050 {
00051   double lambda;
00052 };
00053 
00054 it_function (laplacian_pdf)
00055 {
00056   double lambda = it_this->lambda;  /* variance is 2*lambda^2 */
00057 
00058   return (1. / (2. * lambda) * exp (-fabs (x) / lambda));
00059 }
00060 
00061 void print_quantizer (it_uniform_quantizer_t * SQ)
00062 {
00063   int  _min, _max;
00064 
00065   it_printf ("[Quantizer]\n");
00066   it_printf ("\tdequantize(0) = %f\n", it_dequantize (SQ, 0));
00067   it_printf ("\tstep size: %f\n", it_quantizer_get_step (SQ));
00068   it_printf ("\tcardinal: %d\n", it_quantizer_get_cardinal (SQ));
00069   it_quantizer_get_index_range (SQ, &_min, &_max);
00070   it_printf ("\tindex range: [%d, %d]\n", _min, _max);
00071 }
00072 
00073 void test_quantizer (vec V, it_quantizer_t * quantizer)
00074 {
00075   vec  R;     /* reconstructed vector */
00076   ivec Q;     /* quantized vector     */
00077   vec  H;     /* histogram            */
00078   int  a, b;      /* range of the quantized values */
00079   double error;
00080   double energy;
00081 
00082   it_printf ("quantizing\n");
00083   Q = it_quantize_vec (quantizer, V);
00084 
00085   it_printf ("dequantizing\n");
00086   R = it_dequantize_vec (quantizer, Q);
00087 
00088   energy = vec_variance (V);
00089   error = vec_distance_mse (V, R, 0); /* compute reconstruction error */
00090 
00091   a = ivec_min (Q);
00092   b = ivec_max (Q);
00093   it_printf ("used range: [ %d, %d ]\n", a, b);
00094   ivec_decr (Q, a);
00095   H = histogram_normalized (b - a + 1, Q);
00096   /*
00097      for(int i = 0; i < ivec_length(H); i++)
00098      it_printf("%d\n", H[i]);
00099    */
00100   it_printf ("entropy = %f\n", entropy (H));
00101 
00102   it_printf ("SNR = %f dB\n", 10 * log10 (energy / error));
00103 
00104   vec_delete (R);
00105   vec_delete (H);
00106   ivec_delete (Q);
00107 }
00108 
00109 
00110 int main ()
00111 {
00112   int  i;
00113   vec  codebook;
00114   vec  source;
00115   it_function_args (gaussian_pdf) gaussian_args;
00116   it_function_args (laplacian_pdf) laplacian_args;
00117 
00118   it_scalar_quantizer_t *quantizer;
00119   it_uniform_quantizer_t *uniq;
00120   it_trellis_coded_quantizer_t *tcq;
00121 
00122   /* code used for the TCQ */
00123   it_convolutional_code_t *code;
00124   imat generator = imat_new (1, 2);
00125   generator[0][0] = 0133;
00126   generator[0][1] = 0171;
00127 
00128   /* initialize the random number generator */
00129   //  it_randomize();
00130 
00131   /* random continous vector uniformly distributed in [0,1] */
00132   source = source_uniform_01 (10000);
00133 
00134   /* test a uniform scalar quantizer generated from
00135      its number of bins and the range of the source */
00136   uniq = it_uniform_quantizer_new_from_range (256, 0.0, 1.0);
00137   print_quantizer (uniq);
00138   test_quantizer (source, IT_QUANTIZER (uniq));
00139   it_delete (uniq);
00140 
00141   /* initialize the codebook */
00142   codebook = vec_new (256);
00143   for (i = 0; i < 256; i++)
00144     codebook[i] = i / 256. + 1. / 512.;
00145 
00146   /* test a scalar quantizer generated from a codebook */
00147   quantizer = it_scalar_quantizer_new (codebook);
00148   test_quantizer (source, IT_QUANTIZER (quantizer));
00149   vec_delete (codebook);
00150 
00151   /* test a uniform scalar quantizer generated from
00152      the center (reconstruction value associated to
00153      the zero index) and step, with a deadzone of
00154      twice the normal quantizer step.               */
00155   uniq = it_uniform_quantizer_new_from_center (0, 1. / 256., 2.0);
00156 
00157   /* test quantization/dequantization in the dead zone */
00158   it_printf ("quantize[1/257] = %d\n", it_quantize (uniq, 1 / 257.));
00159   it_printf ("quantize[-1/257] = %d\n", it_quantize (uniq, -1 / 257.));
00160   it_printf ("quantize[-1/255] = %d\n", it_quantize (uniq, -1 / 255.));
00161   it_printf ("dequantize[-1] = %f\n", it_dequantize (uniq, -1));
00162 
00163   /* restrict the index range to -10,10 */
00164   it_quantizer_set_index_range (uniq, -10, 10);
00165 
00166   /* generate and print the resulting codebook */
00167   codebook = it_quantizer_get_codebook (uniq);
00168   it_printf ("codebook = $v\n", codebook);
00169   vec_delete (codebook);
00170 
00171   /* set the index range to 0,1023 and test */
00172   it_quantizer_set_index_range (uniq, 0, 1023);
00173   print_quantizer (uniq);
00174   test_quantizer (source, IT_QUANTIZER (uniq));
00175 
00176   /* get a part of the codebook between 1 and 256 */
00177   codebook = it_quantizer_get_codebook_range (uniq, 1, 256);
00178 
00179   /* use this sub codebook for quantization */
00180   it_quantizer_set_codebook (quantizer, codebook, 1);
00181   test_quantizer (source, IT_QUANTIZER (quantizer));
00182   vec_delete (codebook);
00183   it_delete (uniq);
00184   it_delete (quantizer);
00185 
00186   /* TCQ */
00187   uniq = it_uniform_quantizer_new_from_range (512, 0.0, 1.0);
00188   code = it_convolutional_code_new (generator, 0);
00189   tcq = it_trellis_coded_quantizer_new_partition (code, uniq);
00190 
00191   test_quantizer (source, IT_QUANTIZER (tcq));
00192   it_delete (uniq);
00193   it_delete (tcq);
00194   it_delete (code);
00195 
00196   it_printf ("bound = %f dB\n",
00197        10 * log10 (4) * 8 + 10 * log10 (M_PI * M_E / 6.0));
00198   vec_delete (source);
00199 
00200   /* Lloyd-Max quantization */
00201   gaussian_args.sigma = 1.0;
00202   codebook = lloyd_max (gaussian_pdf, &gaussian_args, -5, 5, 4);
00203 
00204   /* random gaussian vector centered on 0 of variance 1 */
00205   source = source_gaussian (10000, 0, gaussian_args.sigma);
00206   //source = source_pdf(10000, -5, 5, gaussian_pdf, &gaussian_args);
00207 
00208   quantizer = it_scalar_quantizer_new (codebook);
00209   test_quantizer (source, IT_QUANTIZER (quantizer));
00210   vec_delete (codebook);
00211   it_delete (quantizer);
00212   vec_delete (source);
00213 
00214   /* random laplacian vector centered on 0 of variance 1 */
00215   /* (using the acceptance-rejection generator) */
00216   laplacian_args.lambda = 1 / sqrt (2.0);
00217   source = source_pdf (10000, -10, 10, laplacian_pdf, &laplacian_args);
00218   codebook = lloyd_max (laplacian_pdf, &laplacian_args, -10, 10, 4);
00219   quantizer = it_scalar_quantizer_new (codebook);
00220   test_quantizer (source, IT_QUANTIZER (quantizer));
00221   vec_delete (codebook);
00222   it_delete (quantizer);
00223   vec_delete (source);
00224 
00225   /* and now for the Lloyd-Max TCQ */
00226   /* random gaussian vector centered on 0 of variance 1 */
00227   source = source_gaussian (10000, 0, gaussian_args.sigma);
00228   codebook = lloyd_max (gaussian_pdf, &gaussian_args, -5, 5, 16);
00229 
00230   quantizer = it_scalar_quantizer_new (codebook);
00231   test_quantizer (source, IT_QUANTIZER (quantizer));  /* test SQ */
00232 
00233   code = it_convolutional_code_new (generator, 0);
00234   tcq = it_trellis_coded_quantizer_new_partition (code, quantizer);
00235 
00236   test_quantizer (source, IT_QUANTIZER (tcq));
00237   it_delete (quantizer);
00238   it_delete (tcq);
00239   it_delete (code);
00240 
00241   vec_delete (source);
00242 
00243   return (0);
00244 }

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