diff options
Diffstat (limited to 'mbest.c')
| -rw-r--r-- | mbest.c | 194 |
1 files changed, 106 insertions, 88 deletions
| @@ -27,42 +27,48 @@ | |||
| 27 | 27 | ||
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | #include "mbest.h" | ||
| 31 | |||
| 30 | #include <assert.h> | 32 | #include <assert.h> |
| 31 | #include <math.h> | 33 | #include <math.h> |
| 32 | #include <stdio.h> | 34 | #include <stdio.h> |
| 33 | #include <stdlib.h> | 35 | #include <stdlib.h> |
| 34 | #include <string.h> | 36 | #include <string.h> |
| 35 | 37 | ||
| 36 | #include "mbest.h" | ||
| 37 | |||
| 38 | struct MBEST *mbest_create(int entries) { | 38 | struct MBEST *mbest_create(int entries) { |
| 39 | int i,j; | 39 | int i, j; |
| 40 | struct MBEST *mbest; | 40 | struct MBEST *mbest; |
| 41 | 41 | ||
| 42 | assert(entries > 0); | 42 | assert(entries > 0); |
| 43 | mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); | 43 | mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); |
| 44 | assert(mbest != NULL); | 44 | assert(mbest != NULL); |
| 45 | 45 | ||
| 46 | mbest->entries = entries; | 46 | mbest->entries = entries; |
| 47 | mbest->list = (struct MBEST_LIST *)malloc(entries*sizeof(struct MBEST_LIST)); | 47 | mbest->list = |
| 48 | assert(mbest->list != NULL); | 48 | (struct MBEST_LIST *)malloc(entries * sizeof(struct MBEST_LIST)); |
| 49 | assert(mbest->list != NULL); | ||
| 49 | 50 | ||
| 50 | for(i=0; i<mbest->entries; i++) { | 51 | for (i = 0; i < mbest->entries; i++) { |
| 51 | for(j=0; j<MBEST_STAGES; j++) | 52 | for (j = 0; j < MBEST_STAGES; j++) mbest->list[i].index[j] = 0; |
| 52 | mbest->list[i].index[j] = 0; | 53 | mbest->list[i].error = 1E32; |
| 53 | mbest->list[i].error = 1E32; | 54 | } |
| 54 | } | ||
| 55 | 55 | ||
| 56 | return mbest; | 56 | return mbest; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | |||
| 60 | void mbest_destroy(struct MBEST *mbest) { | 59 | void mbest_destroy(struct MBEST *mbest) { |
| 61 | assert(mbest != NULL); | 60 | assert(mbest != NULL); |
| 62 | free(mbest->list); | 61 | free(mbest->list); |
| 63 | free(mbest); | 62 | free(mbest); |
| 64 | } | 63 | } |
| 65 | 64 | ||
| 65 | /* apply weighting to VQ for efficient VQ search */ | ||
| 66 | |||
| 67 | void mbest_precompute_weight(float cb[], float w[], int k, int m) { | ||
| 68 | for (int j = 0; j < m; j++) { | ||
| 69 | for (int i = 0; i < k; i++) cb[k * j + i] *= w[i]; | ||
| 70 | } | ||
| 71 | } | ||
| 66 | 72 | ||
| 67 | /*---------------------------------------------------------------------------*\ | 73 | /*---------------------------------------------------------------------------*\ |
| 68 | 74 | ||
| @@ -75,36 +81,31 @@ void mbest_destroy(struct MBEST *mbest) { | |||
| 75 | \*---------------------------------------------------------------------------*/ | 81 | \*---------------------------------------------------------------------------*/ |
| 76 | 82 | ||
| 77 | void mbest_insert(struct MBEST *mbest, int index[], float error) { | 83 | void mbest_insert(struct MBEST *mbest, int index[], float error) { |
| 78 | int i, j, found; | 84 | int i, found; |
| 79 | struct MBEST_LIST *list = mbest->list; | 85 | struct MBEST_LIST *list = mbest->list; |
| 80 | int entries = mbest->entries; | 86 | int entries = mbest->entries; |
| 81 | 87 | ||
| 82 | found = 0; | 88 | found = 0; |
| 83 | for(i=0; i<entries && !found; i++) | 89 | for (i = 0; i < entries && !found; i++) |
| 84 | if (error < list[i].error) { | 90 | if (error < list[i].error) { |
| 85 | found = 1; | 91 | found = 1; |
| 86 | for(j=entries-1; j>i; j--) | 92 | memmove(&list[i + 1], &list[i], |
| 87 | list[j] = list[j-1]; | 93 | sizeof(struct MBEST_LIST) * (entries - i - 1)); |
| 88 | for(j=0; j<MBEST_STAGES; j++) | 94 | memcpy(&list[i].index[0], &index[0], sizeof(int) * MBEST_STAGES); |
| 89 | list[i].index[j] = index[j]; | 95 | list[i].error = error; |
| 90 | list[i].error = error; | 96 | } |
| 91 | } | ||
| 92 | } | 97 | } |
| 93 | 98 | ||
| 99 | void mbest_print(char title[], struct MBEST *mbest) { | ||
| 100 | int i, j; | ||
| 94 | 101 | ||
| 95 | #ifdef MBEST_PRINT_OUT | 102 | fprintf(stderr, "%s\n", title); |
| 96 | static void mbest_print(char title[], struct MBEST *mbest) { | 103 | for (i = 0; i < mbest->entries; i++) { |
| 97 | int i,j; | 104 | for (j = 0; j < MBEST_STAGES; j++) |
| 98 | 105 | fprintf(stderr, " %4d ", mbest->list[i].index[j]); | |
| 99 | fprintf(stderr, "%s\n", title); | 106 | fprintf(stderr, " %f\n", (double)mbest->list[i].error); |
| 100 | for(i=0; i<mbest->entries; i++) { | 107 | } |
| 101 | for(j=0; j<MBEST_STAGES; j++) | ||
| 102 | fprintf(stderr, " %4d ", mbest->list[i].index[j]); | ||
| 103 | fprintf(stderr, " %f\n", mbest->list[i].error); | ||
| 104 | } | ||
| 105 | } | 108 | } |
| 106 | #endif | ||
| 107 | |||
| 108 | 109 | ||
| 109 | /*---------------------------------------------------------------------------*\ | 110 | /*---------------------------------------------------------------------------*\ |
| 110 | 111 | ||
| @@ -115,31 +116,48 @@ static void mbest_print(char title[], struct MBEST *mbest) { | |||
| 115 | 116 | ||
| 116 | \*---------------------------------------------------------------------------*/ | 117 | \*---------------------------------------------------------------------------*/ |
| 117 | 118 | ||
| 118 | void mbest_search( | 119 | void mbest_search(const float *cb, /* VQ codebook to search */ |
| 119 | const float *cb, /* VQ codebook to search */ | 120 | float vec[], /* target vector */ |
| 120 | float vec[], /* target vector */ | 121 | int k, /* dimension of vector */ |
| 121 | float w[], /* weighting vector */ | 122 | int m, /* number on entries in codebook */ |
| 122 | int k, /* dimension of vector */ | 123 | struct MBEST *mbest, /* list of closest matches */ |
| 123 | int m, /* number on entries in codebook */ | 124 | int index[] /* indexes that lead us here */ |
| 124 | struct MBEST *mbest, /* list of closest matches */ | 125 | ) { |
| 125 | int index[] /* indexes that lead us here */ | 126 | int j; |
| 126 | ) | 127 | |
| 127 | { | 128 | /* note weighting can be applied externally by modifying cb[] and vec: |
| 128 | float e; | 129 | |
| 129 | int i,j; | 130 | float e = 0.0; |
| 130 | float diff; | 131 | for(i=0; i<k; i++) |
| 131 | 132 | e += pow(w[i]*(cb[j*k+i] - vec[i]),2.0) | |
| 132 | for(j=0; j<m; j++) { | 133 | |
| 133 | e = 0.0; | 134 | | |
| 134 | for(i=0; i<k; i++) { | 135 | \|/ |
| 135 | diff = cb[j*k+i]-vec[i]; | 136 | |
| 136 | e += diff*w[i]*diff*w[i]; | 137 | for(i=0; i<k; i++) |
| 137 | } | 138 | e += pow(w[i]*cb[j*k+i] - w[i]*vec[i]),2.0) |
| 138 | index[0] = j; | 139 | |
| 139 | mbest_insert(mbest, index, e); | 140 | | |
| 140 | } | 141 | \|/ |
| 141 | } | ||
| 142 | 142 | ||
| 143 | for(i=0; i<k; i++) | ||
| 144 | e += pow(cb1[j*k+i] - vec1[i]),2.0) | ||
| 145 | |||
| 146 | where cb1[j*k+i] = w[i]*cb[j*k+i], and vec1[i] = w[i]*vec[i] | ||
| 147 | */ | ||
| 148 | |||
| 149 | for (j = 0; j < m; j++) { | ||
| 150 | float e = 0.0; | ||
| 151 | for (int i = 0; i < k; i++) { | ||
| 152 | float diff = *cb++ - vec[i]; | ||
| 153 | e += diff * diff; | ||
| 154 | } | ||
| 155 | |||
| 156 | index[0] = j; | ||
| 157 | if (e < mbest->list[mbest->entries - 1].error) | ||
| 158 | mbest_insert(mbest, index, e); | ||
| 159 | } | ||
| 160 | } | ||
| 143 | 161 | ||
| 144 | /*---------------------------------------------------------------------------*\ | 162 | /*---------------------------------------------------------------------------*\ |
| 145 | 163 | ||
| @@ -148,26 +166,26 @@ void mbest_search( | |||
| 148 | Searches vec[] to a codebbook of vectors, and maintains a list of the mbest | 166 | Searches vec[] to a codebbook of vectors, and maintains a list of the mbest |
| 149 | closest matches. Only searches the first NewAmp2_K Vectors | 167 | closest matches. Only searches the first NewAmp2_K Vectors |
| 150 | 168 | ||
| 151 | \*---------------------------------------------------------------------------*/ | 169 | \*---------------------------------------------------------------------------*/ |
| 152 | 170 | ||
| 153 | void mbest_search450(const float *cb, float vec[], float w[], int k,int shorterK, int m, struct MBEST *mbest, int index[]) | 171 | void mbest_search450(const float *cb, float vec[], float w[], int k, |
| 172 | int shorterK, int m, struct MBEST *mbest, int index[]) | ||
| 154 | 173 | ||
| 155 | { | 174 | { |
| 156 | float e; | 175 | float e; |
| 157 | int i,j; | 176 | int i, j; |
| 158 | float diff; | 177 | float diff; |
| 159 | 178 | ||
| 160 | for(j=0; j<m; j++) { | 179 | for (j = 0; j < m; j++) { |
| 161 | e = 0.0; | 180 | e = 0.0; |
| 162 | for(i=0; i<k; i++) { | 181 | for (i = 0; i < k; i++) { |
| 163 | //Only search first NEWAMP2_K Vectors | 182 | // Only search first NEWAMP2_K Vectors |
| 164 | if(i<shorterK){ | 183 | if (i < shorterK) { |
| 165 | diff = cb[j*k+i]-vec[i]; | 184 | diff = cb[j * k + i] - vec[i]; |
| 166 | e += diff*w[i] * diff*w[i]; | 185 | e += diff * w[i] * diff * w[i]; |
| 167 | } | 186 | } |
| 168 | } | ||
| 169 | index[0] = j; | ||
| 170 | mbest_insert(mbest, index, e); | ||
| 171 | } | 187 | } |
| 188 | index[0] = j; | ||
| 189 | mbest_insert(mbest, index, e); | ||
| 190 | } | ||
| 172 | } | 191 | } |
| 173 | |||
