input: v_ points, might be uncentered k - number of points in the ramp n - number of points in v_ output: index, uncentered, in the range 0..k-1
| 1373 | // index, uncentered, in the range 0..k-1 |
| 1374 | // |
| 1375 | void quant_AnD_Shell(float* v_, int k, int n, int *idx) { |
| 1376 | #define MAX_BLOCK MAX_ENTRIES |
| 1377 | int i, j; |
| 1378 | float v[MAX_BLOCK]; |
| 1379 | float z[MAX_BLOCK]; |
| 1380 | a d[MAX_BLOCK]; |
| 1381 | float l; |
| 1382 | float mm; |
| 1383 | float r = 0; |
| 1384 | int mi; |
| 1385 | |
| 1386 | //assert((v_ != NULL) && (n>1) && (k>1)); |
| 1387 | |
| 1388 | float m, M, s, dm = 0.; |
| 1389 | m = M = v_[0]; |
| 1390 | |
| 1391 | for (i = 1; i < n; i++) { |
| 1392 | m = m < v_[i] ? m : v_[i]; |
| 1393 | M = M > v_[i] ? M : v_[i]; |
| 1394 | } |
| 1395 | if (M == m) { |
| 1396 | for (i = 0; i < n; i++) |
| 1397 | idx[i] = 0; |
| 1398 | return; |
| 1399 | } |
| 1400 | |
| 1401 | //assert(M - m >0); |
| 1402 | s = (k - 1) / (M - m); |
| 1403 | for (i = 0; i < n; i++) { |
| 1404 | v[i] = v_[i] * s; |
| 1405 | |
| 1406 | idx[i] = (int)(z[i] = (v[i] + 0.5f /* stabilizer*/ - m *s)); //floorf(v[i] + 0.5f /* stabilizer*/ - m *s)); |
| 1407 | |
| 1408 | d[i].d = v[i] - z[i] - m *s; |
| 1409 | d[i].i = i; |
| 1410 | dm += d[i].d; |
| 1411 | r += d[i].d*d[i].d; |
| 1412 | } |
| 1413 | if (n*r - dm*dm >= (float)(n - 1) / 4 /*slack*/ / 2) { |
| 1414 | |
| 1415 | dm /= (float)n; |
| 1416 | |
| 1417 | for (i = 0; i < n; i++) |
| 1418 | d[i].d -= dm; |
| 1419 | |
| 1420 | qsort((void*)&d, n, sizeof(a), a_compare); |
| 1421 | |
| 1422 | // got into fundamental simplex |
| 1423 | // move coordinate system origin to its center |
| 1424 | for (i = 0; i < n; i++) |
| 1425 | d[i].d -= (2.0f*(float)i + 1.0f - (float)n) / 2.0f / (float)n; |
| 1426 | |
| 1427 | mm = l = 0.; |
| 1428 | j = -1; |
| 1429 | for (i = 0; i < n; i++) { |
| 1430 | l += d[i].d; |
| 1431 | if (l < mm) { |
| 1432 | mm = l; |