NearestNeighbor.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  NearestNeighbor.cpp
00037 // Author:    Pedram Azad
00038 // Date:      06.10.2009
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs
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 // Constructor / Destructor
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 // Methods
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                 // build values for search tree generation
00120                 for (i = 0; i < nDataSets; i++)
00121                 {
00122                         ppValues[i] = new float[nOverallDimension];
00123                         
00124                         // copy data
00125                         memcpy(ppValues[i], pData + i * nDimension, nDimension * sizeof(float));
00126                         
00127                         // set user data
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; // will never happen
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)); // index
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; // will never happen
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