00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdarg.h>
00026 #include <it/types.h>
00027 #include <it/vec.h>
00028 #include <it/math.h>
00029 #include <it/quantizer.h>
00030 #include <it/io.h>
00031
00032
00033 static void scalar_quantizer_destructor (it_object_t * it_this);
00034 static vec scalar_quantizer_get_codebook_range (it_scalar_quantizer_t * q,
00035 int start, int end);
00036 static void scalar_quantizer_get_index_range (it_scalar_quantizer_t * q,
00037 int *_imin, int *_imax);
00038 static void scalar_quantizer_set_index_range (it_scalar_quantizer_t * q,
00039 int _imin, int _imax);
00040 static int scalar_quantizer_scalar_quantize (it_scalar_quantizer_t * q,
00041 double v);
00042 static double scalar_quantizer_scalar_dequantize (it_scalar_quantizer_t *
00043 it_this, int q);
00044 static void scalar_quantizer_set_codebook (it_scalar_quantizer_t * it_this,
00045 vec codebook, int first);
00046 static ivec scalar_quantizer_quantize (it_quantizer_t * it_this, vec v);
00047 static vec scalar_quantizer_dequantize (it_quantizer_t * it_this, ivec q);
00048 static unsigned int scalar_quantizer_get_cardinal (it_quantizer_t * it_this);
00049
00050 static int uniform_quantizer_scalar_quantize (it_scalar_quantizer_t *
00051 it_this, double v);
00052 static double uniform_quantizer_scalar_dequantize (it_scalar_quantizer_t *
00053 it_this, int q);
00054 static vec uniform_quantizer_get_codebook_range (it_scalar_quantizer_t *
00055 it_this, int s, int e);
00056 static void uniform_quantizer_set_index_range (it_scalar_quantizer_t * q,
00057 int _imin, int _imax);
00058 static void uniform_quantizer_set_codebook (it_scalar_quantizer_t * it_this,
00059 vec codebook, int first);
00060
00061 static void trellis_coded_quantizer_destructor (it_object_t * it_this);
00062 static ivec trellis_coded_quantizer_quantize (it_quantizer_t * it_this,
00063 vec v);
00064 static vec trellis_coded_quantizer_dequantize (it_quantizer_t * it_this,
00065 ivec q);
00066 static unsigned int trellis_coded_quantizer_get_cardinal (it_quantizer_t *
00067 it_this);
00068
00069
00070
00071 it_instanciate (it_scalar_quantizer_t)
00072 {
00073 vec codebook;
00074
00075
00076 it_new_args_start ();
00077
00078
00079 it_construct (it_quantizer_t);
00080
00081
00082 it_set_magic (it_this, it_scalar_quantizer_t);
00083
00084
00085 it_overload (it_this, it_object_t, destructor, scalar_quantizer_destructor);
00086
00087
00088 IT_QUANTIZER (it_this)->quantize = scalar_quantizer_quantize;
00089 IT_QUANTIZER (it_this)->dequantize = scalar_quantizer_dequantize;
00090 IT_QUANTIZER (it_this)->get_cardinal = scalar_quantizer_get_cardinal;
00091 it_this->set_codebook = scalar_quantizer_set_codebook;
00092 it_this->get_codebook_range = scalar_quantizer_get_codebook_range;
00093 it_this->get_index_range = scalar_quantizer_get_index_range;
00094 it_this->set_index_range = scalar_quantizer_set_index_range;
00095 it_this->scalar_quantize = scalar_quantizer_scalar_quantize;
00096 it_this->scalar_dequantize = scalar_quantizer_scalar_dequantize;
00097
00098
00099 codebook = it_new_args_next (vec);
00100 it_this->first = it_new_args_next (int);
00101
00102 if (codebook)
00103 scalar_quantizer_set_codebook (it_this, codebook, it_this->first);
00104 else {
00105 it_this->codebook = NULL;
00106 it_scalar_quantizer_set_index_range (it_this, 0, -1);
00107 }
00108
00109 it_new_args_stop ();
00110 return (it_this);
00111 }
00112
00113 static void scalar_quantizer_destructor (it_object_t * it_this)
00114 {
00115 it_scalar_quantizer_t *scalar_quantizer = IT_SCALAR_QUANTIZER (it_this);
00116
00117 if (scalar_quantizer->codebook)
00118 vec_delete (scalar_quantizer->codebook);
00119
00120
00121 scalar_quantizer->it_overloaded (destructor) (it_this);
00122 }
00123
00124 static vec scalar_quantizer_get_codebook_range (it_scalar_quantizer_t * q,
00125 int start, int end)
00126 {
00127 if (start < q->imin)
00128 start = q->imin;
00129 if (end > q->imax)
00130 end = q->imax;
00131 return (vec_get_subvector (q->codebook, start, end));
00132 }
00133
00134 static void scalar_quantizer_get_index_range (it_scalar_quantizer_t * q,
00135 int *_imin, int *_imax)
00136 {
00137 *_imax = q->imax;
00138 *_imin = q->imin;
00139 }
00140
00141 static void scalar_quantizer_set_index_range (it_scalar_quantizer_t * q,
00142 int _imin, int _imax)
00143 {
00144 if (_imin < _imax) {
00145 q->imax = _imax;
00146 q->imin = _imin;
00147 }
00148 else {
00149 q->imax = _imin;
00150 q->imin = _imax;
00151 }
00152
00153 if (q->imin < q->first)
00154 q->imin = q->first;
00155 if (q->codebook) {
00156 if (q->imax > q->first + (int) vec_length (q->codebook) - 1)
00157 q->imax = q->first + (int) vec_length (q->codebook) - 1;
00158 }
00159 else {
00160 q->imax = q->imin;
00161 }
00162 }
00163
00164
00165 static int scalar_quantizer_scalar_quantize (it_scalar_quantizer_t * q,
00166 double v)
00167 {
00168 int s, e, h;
00169 double c;
00170 int first = q->first;
00171 vec codebook = q->codebook;
00172
00173
00174 s = q->imin - first;
00175 e = q->imax - first;
00176
00177 while (e > s + 1) {
00178
00179 h = (s + e) / 2;
00180 c = codebook[h];
00181
00182
00183 if (v < c)
00184 e = h;
00185 else
00186 s = h;
00187 }
00188
00189
00190 if (v - codebook[s] < codebook[e] - v)
00191 return (s + first);
00192 else
00193 return (e + first);
00194 }
00195
00196
00197 static double scalar_quantizer_scalar_dequantize (it_scalar_quantizer_t *
00198 it_this, int q)
00199 {
00200 int first = it_this->first;
00201 return (it_this->codebook[q - first]);
00202 }
00203
00204
00205 static void scalar_quantizer_set_codebook (it_scalar_quantizer_t * it_this,
00206 vec codebook, int first)
00207 {
00208 if (!codebook) {
00209 fprintf (stderr,
00210 "scalar_quantizer_set_codebook called with a NULL codebook\n");
00211 abort ();
00212 }
00213
00214 it_this->codebook = vec_clone (codebook);
00215 it_this->first = first;
00216 it_scalar_quantizer_set_index_range (it_this, first,
00217 first + vec_length (codebook) - 1);
00218
00219 vec_sort (it_this->codebook);
00220 }
00221
00222
00223 static ivec scalar_quantizer_quantize (it_quantizer_t * it_this, vec v)
00224 {
00225 it_scalar_quantizer_t *scalar_quantizer = IT_SCALAR_QUANTIZER (it_this);
00226 int i;
00227 int l = vec_length (v);
00228 ivec ret = ivec_new (l);
00229
00230 for (i = 0; i < l; i++)
00231 ret[i] = it_scalar_quantizer_scalar_quantize (scalar_quantizer, v[i]);
00232
00233 return (ret);
00234 }
00235
00236
00237 static vec scalar_quantizer_dequantize (it_quantizer_t * it_this, ivec q)
00238 {
00239 it_scalar_quantizer_t *scalar_quantizer = IT_SCALAR_QUANTIZER (it_this);
00240 int i;
00241 int l = ivec_length (q);
00242 vec ret = vec_new (l);
00243
00244 for (i = 0; i < l; i++)
00245 ret[i] = it_scalar_quantizer_scalar_dequantize (scalar_quantizer, q[i]);
00246
00247 return (ret);
00248 }
00249
00250
00251 static unsigned int scalar_quantizer_get_cardinal (it_quantizer_t * it_this)
00252 {
00253 int imin = IT_SCALAR_QUANTIZER (it_this)->imin;
00254 int imax = IT_SCALAR_QUANTIZER (it_this)->imax;
00255
00256 return (imax - imin + 1);
00257 }
00258
00259
00260
00261 it_instanciate (it_uniform_quantizer_t)
00262 {
00263 it_new_args_start ();
00264
00265
00266 it_construct_va (it_scalar_quantizer_t) (it_va, NULL, 0);
00267 it_set_magic (it_this, it_uniform_quantizer_t);
00268
00269
00270 IT_SCALAR_QUANTIZER (it_this)->scalar_quantize =
00271 uniform_quantizer_scalar_quantize;
00272 IT_SCALAR_QUANTIZER (it_this)->scalar_dequantize =
00273 uniform_quantizer_scalar_dequantize;
00274 IT_SCALAR_QUANTIZER (it_this)->get_codebook_range =
00275 uniform_quantizer_get_codebook_range;
00276 IT_SCALAR_QUANTIZER (it_this)->set_index_range =
00277 uniform_quantizer_set_index_range;
00278 IT_SCALAR_QUANTIZER (it_this)->set_codebook =
00279 uniform_quantizer_set_codebook;
00280
00281
00282 it_this->center = it_new_args_next (double);
00283 it_this->step = it_new_args_next (double);
00284 it_this->factor = it_new_args_next (double);
00285 it_this->deadzone = it_this->step * it_this->factor;
00286 it_scalar_quantizer_clear_index_range (it_this);
00287
00288 it_new_args_stop ();
00289 return (it_this);
00290 }
00291
00292 static int uniform_quantizer_scalar_quantize (it_scalar_quantizer_t *
00293 it_this, double v)
00294 {
00295 int imin = it_this->imin;
00296 int imax = it_this->imax;
00297 double min = IT_UNIFORM_QUANTIZER (it_this)->min;
00298 double max = IT_UNIFORM_QUANTIZER (it_this)->max;
00299 double center = it_quantizer_get_center (it_this);
00300 double step = it_quantizer_get_step (it_this);
00301 double dead_step = it_quantizer_get_deadzone_step (it_this);
00302
00303 if (v <= min)
00304 return (imin);
00305 if (v >= max)
00306 return (imax);
00307
00308 v -= center;
00309
00310 if (v > 0)
00311 return ((int) ((v + step - dead_step / 2) / step));
00312 else
00313 return ((int) ((v - step + dead_step / 2) / step));
00314 }
00315
00316
00317 static double uniform_quantizer_scalar_dequantize (it_scalar_quantizer_t *
00318 it_this, int q)
00319 {
00320 double center = it_quantizer_get_center (it_this);
00321 double step = it_quantizer_get_step (it_this);
00322 double dead_step = it_quantizer_get_deadzone_step (it_this);
00323
00324 if (q == 0)
00325 return (center);
00326
00327 if (q > 0)
00328 return (center + q * step + (dead_step - step) / 2);
00329 else
00330 return (center + q * step - (dead_step - step) / 2);
00331 }
00332
00333
00334 static vec uniform_quantizer_get_codebook_range (it_scalar_quantizer_t *
00335 it_this, int s, int e)
00336 {
00337 int imin = it_this->imin;
00338 int imax = it_this->imax;
00339 vec book;
00340 int i;
00341
00342 if (it_this->codebook)
00343 return (it_scalar_quantizer_get_codebook_range (it_this, s, e));
00344
00345 if (s < imin)
00346 s = imin;
00347 if (e > imax)
00348 e = imax;
00349 book = vec_new (e - s + 1);
00350
00351 for (i = s; i <= e; i++)
00352 book[i - s] = it_scalar_quantizer_scalar_dequantize (it_this, i);
00353
00354 return (book);
00355 }
00356
00357 static void uniform_quantizer_set_index_range (it_scalar_quantizer_t *
00358 it_this, int _imin, int _imax)
00359 {
00360 if (_imin < _imax) {
00361 it_this->imax = _imax;
00362 it_this->imin = _imin;
00363 }
00364 else {
00365 it_this->imax = _imin;
00366 it_this->imin = _imax;
00367 }
00368
00369 IT_UNIFORM_QUANTIZER (it_this)->min = it_dequantize (it_this, _imin);
00370 IT_UNIFORM_QUANTIZER (it_this)->max = it_dequantize (it_this, _imax);
00371 }
00372
00373
00374 static void uniform_quantizer_set_codebook (it_scalar_quantizer_t * it_this,
00375 vec codebook, int first)
00376 {
00377 fprintf (stderr, "cannot change the codebook of a uniform quantizer\n");
00378 abort ();
00379 }
00380
00381
00382
00383
00384 #define gray_to_bin(x) ((x) ^ (x >> 1))
00385
00386 it_instanciate (it_trellis_coded_quantizer_t)
00387 {
00388 int i, j, k;
00389 int n, r, m;
00390
00391 vec codebook;
00392 vec subcodebook;
00393 it_convolutional_code_t *code;
00394 it_scalar_quantizer_t *quantizer;
00395 it_scalar_quantizer_t **coset_quantizers;
00396
00397 it_new_args_start ();
00398
00399 it_construct (it_quantizer_t);
00400 it_set_magic (it_this, it_trellis_coded_quantizer_t);
00401
00402
00403 it_overload (it_this, it_object_t, destructor,
00404 trellis_coded_quantizer_destructor);
00405 IT_QUANTIZER (it_this)->quantize = trellis_coded_quantizer_quantize;
00406 IT_QUANTIZER (it_this)->dequantize = trellis_coded_quantizer_dequantize;
00407 IT_QUANTIZER (it_this)->get_cardinal = trellis_coded_quantizer_get_cardinal;
00408
00409
00410 code = it_new_args_next (it_convolutional_code_t *);
00411 quantizer = it_new_args_next (it_scalar_quantizer_t *);
00412 it_this->code = code;
00413
00414
00415 codebook = it_quantizer_get_codebook (quantizer);
00416 n = vec_length (codebook);
00417 r = code->n;
00418 m = (1 << r);
00419
00420
00421 it_this->coset_quantizers = coset_quantizers =
00422 (it_scalar_quantizer_t **) malloc (m * sizeof (it_scalar_quantizer_t *));
00423
00424 for (j = 0; j < m; j++) {
00425 subcodebook = vec_new ((n + m - j - 1) / m);
00426
00427 for (i = j, k = 0; i < n; i += m, k++)
00428 subcodebook[k] = codebook[i];
00429
00430 coset_quantizers[gray_to_bin (j)] = it_scalar_quantizer_new (subcodebook);
00431 vec_delete (subcodebook);
00432 }
00433
00434 it_new_args_stop ();
00435 return (it_this);
00436 }
00437
00438
00439 static void trellis_coded_quantizer_destructor (it_object_t * it_this)
00440 {
00441 it_trellis_coded_quantizer_t *tcq = IT_TRELLIS_CODED_QUANTIZER (it_this);
00442 it_scalar_quantizer_t **coset_quantizers = tcq->coset_quantizers;
00443 int m = 1 << tcq->code->n;
00444 int i;
00445
00446 for (i = 0; i < m; i++)
00447 it_delete (coset_quantizers[i]);
00448
00449
00450
00451
00452 tcq->it_overloaded (destructor) (it_this);
00453 }
00454
00455
00456 static ivec trellis_coded_quantizer_quantize (it_quantizer_t * it_this, vec v)
00457 {
00458 it_trellis_coded_quantizer_t *tcq = IT_TRELLIS_CODED_QUANTIZER (it_this);
00459 it_scalar_quantizer_t **coset_quantizers = tcq->coset_quantizers;
00460 it_convolutional_code_t *cc = tcq->code;
00461 mat metrics;
00462 imat bestword;
00463 int i, j, q;
00464 double r;
00465 int l = vec_length (v);
00466 int n_labels = cc->n_labels;
00467 ivec ret = ivec_new (l);
00468 ivec path;
00469 ivec books;
00470
00471
00472 metrics = mat_new (n_labels, l);
00473 bestword = imat_new (n_labels, l);
00474
00475 for (i = 0; i < l; i++)
00476 for (j = 0; j < n_labels; j++) {
00477
00478 q = it_quantize (coset_quantizers[j], v[i]);
00479 r = it_dequantize (coset_quantizers[j], q);
00480
00481 metrics[j][i] = -(r - v[i]) * (r - v[i]);
00482 bestword[j][i] = q;
00483 }
00484
00485
00486 path = it_viterbi_decode_symbolic (cc, metrics);
00487
00488
00489 books = it_cc_encode_symbolic (cc, path);
00490
00491
00492 for (i = 0; i < l; i++)
00493 ret[i] = (bestword[books[i]][i] << 1) | path[i];
00494
00495 mat_delete (metrics);
00496 imat_delete (bestword);
00497
00498 ivec_delete (path);
00499 ivec_delete (books);
00500
00501 return (ret);
00502 }
00503
00504
00505 static vec trellis_coded_quantizer_dequantize (it_quantizer_t * it_this,
00506 ivec q)
00507 {
00508 it_trellis_coded_quantizer_t *tcq = IT_TRELLIS_CODED_QUANTIZER (it_this);
00509 it_scalar_quantizer_t **coset_quantizers = tcq->coset_quantizers;
00510 it_convolutional_code_t *cc = tcq->code;
00511 int i;
00512 int l = ivec_length (q);
00513 vec ret = vec_new (l);
00514 ivec path;
00515 ivec books;
00516 int word;
00517
00518
00519 path = ivec_new (l);
00520 for (i = 0; i < l; i++)
00521 path[i] = q[i] & 1;
00522
00523
00524 books = it_cc_encode_symbolic (cc, path);
00525
00526
00527 for (i = 0; i < l; i++) {
00528 word = q[i] >> 1;
00529 ret[i] = it_dequantize (coset_quantizers[books[i]], word);
00530 }
00531
00532 ivec_delete (path);
00533 ivec_delete (books);
00534 return (ret);
00535 }
00536
00537
00538
00539 static unsigned int trellis_coded_quantizer_get_cardinal (it_quantizer_t *
00540 it_this)
00541 {
00542 it_trellis_coded_quantizer_t *tcq = IT_TRELLIS_CODED_QUANTIZER (it_this);
00543 it_convolutional_code_t *cc = tcq->code;
00544 int k = cc->k;
00545 int c = it_quantizer_get_cardinal (tcq->coset_quantizers[0]);
00546
00547 return ((1 << k) * c);
00548 }
00549
00550
00551
00552
00553
00554 it_function_args (lloyd_max_distortion)
00555 {
00556 double expectation;
00557 it_function_t function;
00558 it_args_t args;
00559 };
00560
00561 it_function (lloyd_max_distortion)
00562 {
00563 double E = it_this->expectation;
00564 it_function_t f = it_this->function;
00565 it_args_t args = it_this->args;
00566 double d;
00567
00568 d = x - E;
00569
00570 return (d * d * f (x, args));
00571 }
00572
00573
00574
00575
00576
00577 vec lloyd_max (it_function_t function, it_args_t args,
00578 double a, double b, int N)
00579 {
00580
00581 double step = (b - a) / N;
00582 vec threshold = vec_new_arithm (a, step, N + 1);
00583 vec codebook = vec_new_arithm (a, step, N);
00584 int i;
00585 double density;
00586 double expectation;
00587 double distortion, old_distortion;
00588 it_function_args (itf_integrate) density_args;
00589 it_function_args (itf_expectation) expectation_args;
00590 it_function_args (lloyd_max_distortion) distortion_args;
00591 it_function_args (itf_integrate) integrate_args;
00592
00593
00594 density_args.function = function;
00595 density_args.args = args;
00596
00597 expectation_args.function = function;
00598 expectation_args.args = args;
00599
00600 distortion_args.function = function;
00601 distortion_args.args = args;
00602 integrate_args.function = lloyd_max_distortion;
00603 integrate_args.args = &distortion_args;
00604
00605 distortion = HUGE_VAL;
00606
00607 do {
00608
00609 old_distortion = distortion;
00610 distortion = 0;
00611
00612
00613 for (i = 0; i < N; i++) {
00614
00615 density_args.a = threshold[i];
00616 density = itf_integrate (threshold[i + 1], &density_args);
00617
00618
00619 expectation_args.a = threshold[i];
00620 expectation = itf_expectation (threshold[i + 1], &expectation_args);
00621
00622 codebook[i] = expectation / density;
00623
00624
00625 integrate_args.a = threshold[i];
00626 distortion_args.expectation = codebook[i];
00627 distortion += itf_integrate (threshold[i + 1], &integrate_args);
00628 }
00629
00630
00631 for (i = 0; i < N - 1; i++)
00632 threshold[i + 1] = (codebook[i] + codebook[i + 1]) / 2.0;
00633
00634 }
00635 while ((old_distortion - distortion) / distortion > IT_EPSILON);
00636
00637 return (codebook);
00638 }
00639
00640
00641 imat __it_quantize_mat (it_quantizer_t * q, mat m)
00642 {
00643 idx_t i, h;
00644 imat r;
00645 h = mat_height (m);
00646 r = (ivec *) Vec_new (ivec, h);
00647 for (i = 0; i < h; i++)
00648 r[i] = it_quantize_vec (q, m[i]);
00649 return (r);
00650 }
00651
00652
00653 mat __it_dequantize_mat (it_quantizer_t * q, imat m)
00654 {
00655 idx_t i, h;
00656 mat r;
00657 h = imat_height (m);
00658 r = (vec *) Vec_new (vec, h);
00659 for (i = 0; i < h; i++)
00660 r[i] = it_dequantize_vec (q, m[i]);
00661 return (r);
00662 }