void ff_do_elbg(int *points, int dim, int numpoints, int *codebook,

                int numCB, int max_steps, int *closest_cb,

                AVLFG *rand_state)

{

    int dist;

    elbg_data elbg_d;

    elbg_data *elbg = &elbg_d;

    int i, j, k, last_error, steps=0;

    int *dist_cb = av_malloc(numpoints*sizeof(int));

    int *size_part = av_malloc(numCB*sizeof(int));

    cell *list_buffer = av_malloc(numpoints*sizeof(cell));

    cell *free_cells;

    int best_dist, best_idx = 0;



    elbg->error = INT_MAX;

    elbg->dim = dim;

    elbg->numCB = numCB;

    elbg->codebook = codebook;

    elbg->cells = av_malloc(numCB*sizeof(cell *));

    elbg->utility = av_malloc(numCB*sizeof(int));

    elbg->nearest_cb = closest_cb;

    elbg->points = points;

    elbg->utility_inc = av_malloc(numCB*sizeof(int));

    elbg->scratchbuf = av_malloc(5*dim*sizeof(int));



    elbg->rand_state = rand_state;



    do {

        free_cells = list_buffer;

        last_error = elbg->error;

        steps++;

        memset(elbg->utility, 0, numCB*sizeof(int));

        memset(elbg->cells, 0, numCB*sizeof(cell *));



        elbg->error = 0;



        /* This loop evaluate the actual Voronoi partition. It is the most

           costly part of the algorithm. */

        for (i=0; i < numpoints; i++) {

            best_dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + best_idx*elbg->dim, dim, INT_MAX);

            for (k=0; k < elbg->numCB; k++) {

                dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, best_dist);

                if (dist < best_dist) {

                    best_dist = dist;

                    best_idx = k;

                }

            }

            elbg->nearest_cb[i] = best_idx;

            dist_cb[i] = best_dist;

            elbg->error += dist_cb[i];

            elbg->utility[elbg->nearest_cb[i]] += dist_cb[i];

            free_cells->index = i;

            free_cells->next = elbg->cells[elbg->nearest_cb[i]];

            elbg->cells[elbg->nearest_cb[i]] = free_cells;

            free_cells++;

        }



        do_shiftings(elbg);



        memset(size_part, 0, numCB*sizeof(int));



        memset(elbg->codebook, 0, elbg->numCB*dim*sizeof(int));



        for (i=0; i < numpoints; i++) {

            size_part[elbg->nearest_cb[i]]++;

            for (j=0; j < elbg->dim; j++)

                elbg->codebook[elbg->nearest_cb[i]*elbg->dim + j] +=

                    elbg->points[i*elbg->dim + j];

        }



        for (i=0; i < elbg->numCB; i++)

            vect_division(elbg->codebook + i*elbg->dim,

                          elbg->codebook + i*elbg->dim, size_part[i], elbg->dim);



    } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) &&

            (steps < max_steps));



    av_free(dist_cb);

    av_free(size_part);

    av_free(elbg->utility);

    av_free(list_buffer);

    av_free(elbg->cells);

    av_free(elbg->utility_inc);

    av_free(elbg->scratchbuf);

}

void ff_do_elbg(int *points, int dim, int numpoints, int *codebook,

                int numCB, int max_steps, int *closest_cb,

                AVLFG *rand_state)

{

    int dist;

    elbg_data elbg_d;

    elbg_data *elbg = &elbg_d;

    int i, j, k, last_error, steps=0;

    int *dist_cb = av_malloc(numpoints*sizeof(int));

    int *size_part = av_malloc(numCB*sizeof(int));

    cell *list_buffer = av_malloc(numpoints*sizeof(cell));

    cell *free_cells;

    int best_dist, best_idx = 0;



    elbg->error = INT_MAX;

    elbg->dim = dim;

    elbg->numCB = numCB;

    elbg->codebook = codebook;

    elbg->cells = av_malloc(numCB*sizeof(cell *));

    elbg->utility = av_malloc(numCB*sizeof(int));

    elbg->nearest_cb = closest_cb;

    elbg->points = points;

    elbg->utility_inc = av_malloc(numCB*sizeof(int));

    elbg->scratchbuf = av_malloc(5*dim*sizeof(int));



    elbg->rand_state = rand_state;



    do {

        free_cells = list_buffer;

        last_error = elbg->error;

        steps++;

        memset(elbg->utility, 0, numCB*sizeof(int));

        memset(elbg->cells, 0, numCB*sizeof(cell *));



        elbg->error = 0;



        



        for (i=0; i < numpoints; i++) {

            best_dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + best_idx*elbg->dim, dim, INT_MAX);

            for (k=0; k < elbg->numCB; k++) {

                dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, best_dist);

                if (dist < best_dist) {

                    best_dist = dist;

                    best_idx = k;

                }

            }

            elbg->nearest_cb[i] = best_idx;

            dist_cb[i] = best_dist;

            elbg->error += dist_cb[i];

            elbg->utility[elbg->nearest_cb[i]] += dist_cb[i];

            free_cells->index = i;

            free_cells->next = elbg->cells[elbg->nearest_cb[i]];

            elbg->cells[elbg->nearest_cb[i]] = free_cells;

            free_cells++;

        }



        do_shiftings(elbg);



        memset(size_part, 0, numCB*sizeof(int));



        memset(elbg->codebook, 0, elbg->numCB*dim*sizeof(int));



        for (i=0; i < numpoints; i++) {

            size_part[elbg->nearest_cb[i]]++;

            for (j=0; j < elbg->dim; j++)

                elbg->codebook[elbg->nearest_cb[i]*elbg->dim + j] +=

                    elbg->points[i*elbg->dim + j];

        }



        for (i=0; i < elbg->numCB; i++)

            vect_division(elbg->codebook + i*elbg->dim,

                          elbg->codebook + i*elbg->dim, size_part[i], elbg->dim);



    } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) &&

            (steps < max_steps));



    av_free(dist_cb);

    av_free(size_part);

    av_free(elbg->utility);

    av_free(list_buffer);

    av_free(elbg->cells);

    av_free(elbg->utility_inc);

    av_free(elbg->scratchbuf);

}

void FUNC_0(int *VAR_0, int VAR_1, int VAR_2, int *VAR_3,

                int VAR_4, int VAR_5, int *VAR_6,

                AVLFG *VAR_7)

{

    int VAR_8;

    elbg_data elbg_d;

    elbg_data *elbg = &elbg_d;

    int VAR_9, VAR_10, VAR_11, VAR_12, VAR_13=0;

    int *VAR_14 = av_malloc(VAR_2*sizeof(int));

    int *VAR_15 = av_malloc(VAR_4*sizeof(int));

    cell *list_buffer = av_malloc(VAR_2*sizeof(cell));

    cell *free_cells;

    int VAR_16, VAR_17 = 0;



    elbg->error = INT_MAX;

    elbg->VAR_1 = VAR_1;

    elbg->VAR_4 = VAR_4;

    elbg->VAR_3 = VAR_3;

    elbg->cells = av_malloc(VAR_4*sizeof(cell *));

    elbg->utility = av_malloc(VAR_4*sizeof(int));

    elbg->nearest_cb = VAR_6;

    elbg->VAR_0 = VAR_0;

    elbg->utility_inc = av_malloc(VAR_4*sizeof(int));

    elbg->scratchbuf = av_malloc(5*VAR_1*sizeof(int));



    elbg->VAR_7 = VAR_7;



    do {

        free_cells = list_buffer;

        VAR_12 = elbg->error;

        VAR_13++;

        memset(elbg->utility, 0, VAR_4*sizeof(int));

        memset(elbg->cells, 0, VAR_4*sizeof(cell *));



        elbg->error = 0;



        



        for (VAR_9=0; VAR_9 < VAR_2; VAR_9++) {

            VAR_16 = distance_limited(elbg->VAR_0 + VAR_9*elbg->VAR_1, elbg->VAR_3 + VAR_17*elbg->VAR_1, VAR_1, INT_MAX);

            for (VAR_11=0; VAR_11 < elbg->VAR_4; VAR_11++) {

                VAR_8 = distance_limited(elbg->VAR_0 + VAR_9*elbg->VAR_1, elbg->VAR_3 + VAR_11*elbg->VAR_1, VAR_1, VAR_16);

                if (VAR_8 < VAR_16) {

                    VAR_16 = VAR_8;

                    VAR_17 = VAR_11;

                }

            }

            elbg->nearest_cb[VAR_9] = VAR_17;

            VAR_14[VAR_9] = VAR_16;

            elbg->error += VAR_14[VAR_9];

            elbg->utility[elbg->nearest_cb[VAR_9]] += VAR_14[VAR_9];

            free_cells->index = VAR_9;

            free_cells->next = elbg->cells[elbg->nearest_cb[VAR_9]];

            elbg->cells[elbg->nearest_cb[VAR_9]] = free_cells;

            free_cells++;

        }



        do_shiftings(elbg);



        memset(VAR_15, 0, VAR_4*sizeof(int));



        memset(elbg->VAR_3, 0, elbg->VAR_4*VAR_1*sizeof(int));



        for (VAR_9=0; VAR_9 < VAR_2; VAR_9++) {

            VAR_15[elbg->nearest_cb[VAR_9]]++;

            for (VAR_10=0; VAR_10 < elbg->VAR_1; VAR_10++)

                elbg->VAR_3[elbg->nearest_cb[VAR_9]*elbg->VAR_1 + VAR_10] +=

                    elbg->VAR_0[VAR_9*elbg->VAR_1 + VAR_10];

        }



        for (VAR_9=0; VAR_9 < elbg->VAR_4; VAR_9++)

            vect_division(elbg->VAR_3 + VAR_9*elbg->VAR_1,

                          elbg->VAR_3 + VAR_9*elbg->VAR_1, VAR_15[VAR_9], elbg->VAR_1);



    } while(((VAR_12 - elbg->error) > DELTA_ERR_MAX*elbg->error) &&

            (VAR_13 < VAR_5));



    av_free(VAR_14);

    av_free(VAR_15);

    av_free(elbg->utility);

    av_free(list_buffer);

    av_free(elbg->cells);

    av_free(elbg->utility_inc);

    av_free(elbg->scratchbuf);

}

void FUNC_0(int *VAR_0, int VAR_1, int VAR_2, int *VAR_3,
int VAR_4, int VAR_5, int *VAR_6,
AVLFG *VAR_7)
{ int VAR_8; elbg_data elbg_d; elbg_data *elbg = &elbg_d; int VAR_9, VAR_10, VAR_11, VAR_12, VAR_13=0; int *VAR_14 = av_malloc(VAR_2*sizeof(int)); int *VAR_15 = av_malloc(VAR_4*sizeof(int)); cell *list_buffer = av_malloc(VAR_2*sizeof(cell)); cell *free_cells; int VAR_16, VAR_17 = 0; elbg->error = INT_MAX; elbg->VAR_1 = VAR_1; elbg->VAR_4 = VAR_4; elbg->VAR_3 = VAR_3; elbg->cells = av_malloc(VAR_4*sizeof(cell *)); elbg->utility = av_malloc(VAR_4*sizeof(int)); elbg->nearest_cb = VAR_6; elbg->VAR_0 = VAR_0; elbg->utility_inc = av_malloc(VAR_4*sizeof(int)); elbg->scratchbuf = av_malloc(5*VAR_1*sizeof(int)); elbg->VAR_7 = VAR_7; do { free_cells = list_buffer; VAR_12 = elbg->error; VAR_13++; memset(elbg->utility, 0, VAR_4*sizeof(int)); memset(elbg->cells, 0, VAR_4*sizeof(cell *)); elbg->error = 0; for (VAR_9=0; VAR_9 < VAR_2; VAR_9++) { VAR_16 = distance_limited(elbg->VAR_0 + VAR_9*elbg->VAR_1, elbg->VAR_3 + VAR_17*elbg->VAR_1, VAR_1, INT_MAX); for (VAR_11=0; VAR_11 < elbg->VAR_4; VAR_11++) { VAR_8 = distance_limited(elbg->VAR_0 + VAR_9*elbg->VAR_1, elbg->VAR_3 + VAR_11*elbg->VAR_1, VAR_1, VAR_16); if (VAR_8 < VAR_16) { VAR_16 = VAR_8; VAR_17 = VAR_11; } } elbg->nearest_cb[VAR_9] = VAR_17; VAR_14[VAR_9] = VAR_16; elbg->error += VAR_14[VAR_9]; elbg->utility[elbg->nearest_cb[VAR_9]] += VAR_14[VAR_9]; free_cells->index = VAR_9; free_cells->next = elbg->cells[elbg->nearest_cb[VAR_9]]; elbg->cells[elbg->nearest_cb[VAR_9]] = free_cells; free_cells++; } do_shiftings(elbg); memset(VAR_15, 0, VAR_4*sizeof(int)); memset(elbg->VAR_3, 0, elbg->VAR_4*VAR_1*sizeof(int)); for (VAR_9=0; VAR_9 < VAR_2; VAR_9++) { VAR_15[elbg->nearest_cb[VAR_9]]++; for (VAR_10=0; VAR_10 < elbg->VAR_1; VAR_10++) elbg->VAR_3[elbg->nearest_cb[VAR_9]*elbg->VAR_1 + VAR_10] +=
elbg->VAR_0[VAR_9*elbg->VAR_1 + VAR_10]; } for (VAR_9=0; VAR_9 < elbg->VAR_4; VAR_9++) vect_division(elbg->VAR_3 + VAR_9*elbg->VAR_1,
elbg->VAR_3 + VAR_9*elbg->VAR_1, VAR_15[VAR_9], elbg->VAR_1); } while(((VAR_12 - elbg->error) > DELTA_ERR_MAX*elbg->error) && (VAR_13 < VAR_5)); av_free(VAR_14); av_free(VAR_15); av_free(elbg->utility); av_free(list_buffer); av_free(elbg->cells); av_free(elbg->utility_inc); av_free(elbg->scratchbuf); }