Go to the documentation of this file.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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <new>
00047
00048 #include "NearestNeighbor.h"
00049 #include "DataStructures/KdTree/KdTree.h"
00050 #include "Helpers/OptimizedFunctions.h"
00051
00052 #include <string.h>
00053 #include <float.h>
00054 #include <math.h>
00055 #include <stdio.h>
00056
00057
00058
00059
00060
00061
00062
00063 CNearestNeighbor::CNearestNeighbor(ComputationMethod method)
00064 {
00065 m_pData = 0;
00066 m_pKdTree = 0;
00067 m_nDimension = 0;
00068 m_nDataSets = 0;
00069 m_nKdTreeMaxLeaves = -1;
00070 m_method = method;
00071 m_bTrained = false;
00072 }
00073
00074 CNearestNeighbor::~CNearestNeighbor()
00075 {
00076 if (m_pData)
00077 delete [] m_pData;
00078
00079 if (m_pKdTree)
00080 delete m_pKdTree;
00081
00082 OPTIMIZED_FUNCTION_HEADER_0(NearestNeighbor_CleanupGPU)
00083 OPTIMIZED_FUNCTION_FOOTER
00084 }
00085
00086
00087
00088
00089
00090
00091 bool CNearestNeighbor::Train(const float *pData, int nDimension, int nDataSets)
00092 {
00093 if (nDataSets < 1)
00094 {
00095 m_bTrained = false;
00096 return false;
00097 }
00098
00099 m_nDimension = nDimension;
00100 m_nDataSets = nDataSets;
00101 m_bTrained = false;
00102
00103 if (m_method == eBruteForce)
00104 {
00105 if (m_pData)
00106 delete [] m_pData;
00107
00108 m_pData = new float[nDimension * nDataSets];
00109
00110 memcpy(m_pData, pData, nDimension * nDataSets * sizeof(float));
00111 }
00112 else if (m_method == eKdTree)
00113 {
00114 const int nOverallDimension = nDimension + 2;
00115 int i;
00116
00117 float **ppValues = new float*[nDataSets];
00118
00119
00120 for (i = 0; i < nDataSets; i++)
00121 {
00122 ppValues[i] = new float[nOverallDimension];
00123
00124
00125 memcpy(ppValues[i], pData + i * nDimension, nDimension * sizeof(float));
00126
00127
00128 memcpy(&ppValues[i][nDimension], &i, sizeof(int));
00129 }
00130
00131 if (m_pKdTree)
00132 delete m_pKdTree;
00133
00134 m_pKdTree = new CKdTree();
00135 m_pKdTree->Build(ppValues, 0, nDataSets - 1, 3, nDimension, 2);
00136
00137 for (i = 0; i < nDataSets; i++)
00138 delete [] ppValues[i];
00139
00140 delete [] ppValues;
00141 }
00142 else if (m_method == eBruteForceGPU)
00143 {
00144 OPTIMIZED_FUNCTION_HEADER_3(NearestNeighbor_TrainGPU, pData, nDimension, nDataSets)
00145 return false;
00146 OPTIMIZED_FUNCTION_FOOTER
00147 }
00148
00149 m_bTrained = true;
00150
00151 return true;
00152 }
00153
00154 int CNearestNeighbor::Classify(const float *pQuery, int nDimension, float &fResultError)
00155 {
00156 if (!m_bTrained)
00157 {
00158 printf("error: classifier not trained in CNearestNeighbor::Classify\n");
00159 return -1;
00160 }
00161
00162 if (m_nDimension != nDimension)
00163 {
00164 printf("error: query dimension and trained dimension do not match in CNearestNeighbor::Classify\n");
00165 return -1;
00166 }
00167
00168 if (m_method == eBruteForce)
00169 {
00170 const float *pData = m_pData;
00171
00172 int best_i = -1;
00173 float min = FLT_MAX;
00174
00175 for (int i = 0; i < m_nDataSets; i++)
00176 {
00177 float error = 0.0f;
00178
00179 for (int j = 0; j < m_nDimension; j++)
00180 {
00181 register float v = pQuery[j] - pData[j];
00182 error += v * v;
00183 }
00184
00185 if (error < min)
00186 {
00187 min = error;
00188 best_i = i;
00189 }
00190
00191 pData += m_nDimension;
00192 }
00193
00194 fResultError = min;
00195
00196 return best_i;
00197 }
00198 else if (m_method == eKdTree)
00199 {
00200 float *pData, error;
00201 m_pKdTree->NearestNeighborBBF(pQuery, error, pData, m_nKdTreeMaxLeaves);
00202
00203 int nResultIndex;
00204 memcpy(&nResultIndex, pData + m_nDimension, sizeof(int));
00205
00206 fResultError = error;
00207
00208 return nResultIndex;
00209 }
00210 else if (m_method == eBruteForceGPU)
00211 {
00212 int nResult;
00213 OPTIMIZED_FUNCTION_HEADER_4(NearestNeighbor_ClassifyGPU, pQuery, nDimension, nResult, fResultError)
00214 return nResult;
00215 OPTIMIZED_FUNCTION_FOOTER
00216 }
00217
00218 return -1;
00219 }
00220
00221 bool CNearestNeighbor::Classify(const float *pQueries, int nDimension, int nQueries, int *pResults, float *pResultErrors)
00222 {
00223 if (!m_bTrained)
00224 {
00225 printf("error: classifier not trained in CNearestNeighbor::Classify\n");
00226 return false;
00227 }
00228
00229 if (m_nDimension != nDimension)
00230 {
00231 printf("error: query dimension and trained dimension do not match in CNearestNeighbor::Classify\n");
00232 return false;
00233 }
00234
00235 if (m_method == eBruteForce)
00236 {
00237 const float *pQuery = pQueries;
00238
00239 for (int k = 0; k < nQueries; k++)
00240 {
00241 const float *pData = m_pData;
00242
00243 int best_i = -1;
00244 float min = FLT_MAX;
00245
00246 for (int i = 0; i < m_nDataSets; i++)
00247 {
00248 float error = 0.0f;
00249
00250 for (int j = 0; j < m_nDimension; j++)
00251 {
00252 register float v = pQuery[j] - pData[j];
00253 error += v * v;
00254 }
00255
00256 if (error < min)
00257 {
00258 min = error;
00259 best_i = i;
00260 }
00261
00262 pData += m_nDimension;
00263 }
00264
00265 pResults[k] = best_i;
00266 pResultErrors[k] = min;
00267
00268 pQuery += m_nDimension;
00269 }
00270
00271 return true;
00272 }
00273 else if (m_method == eKdTree)
00274 {
00275 const float *pQuery = pQueries;
00276
00277 for (int k = 0; k < nQueries; k++)
00278 {
00279 float *pData, error;
00280 m_pKdTree->NearestNeighborBBF(pQuery, error, pData, m_nKdTreeMaxLeaves);
00281
00282 memcpy(pResults + k, pData + m_nDimension, sizeof(int));
00283 pResultErrors[k] = error;
00284
00285 pQuery += m_nDimension;
00286 }
00287
00288 return true;
00289 }
00290 else if (m_method == eBruteForceGPU)
00291 {
00292 OPTIMIZED_FUNCTION_HEADER_5(NearestNeighbor_ClassifyBundleGPU, pQueries, nDimension, nQueries, pResults, pResultErrors)
00293 return false;
00294 OPTIMIZED_FUNCTION_FOOTER
00295 return true;
00296 }
00297
00298 return false;
00299 }
asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:57