Created
July 9, 2015 16:27
-
-
Save RobertKrajewski/042ab741809cb41b0346 to your computer and use it in GitHub Desktop.
Lazy interpolation template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef LAZYINTERPOLATION_H | |
#define LAZYINTERPOLATION_H | |
#include <functional> | |
/** | |
* @brief This class manages data interpolation and saves results. | |
* During construction a vector containing data is passed. Interpolated | |
* data is saved in this class and another interpolation is avoided. | |
*/ | |
template< template< typename > class Vector, class T > | |
class LazyInterpolation | |
{ | |
public: | |
LazyInterpolation( Vector< T > *f_data_p, | |
std::function< int( T* , T* ) > f_compare_f, | |
std::function< void( T*, T*, T&) > f_interpolate_f ) | |
: m_inputData_p( f_data_p ), | |
m_interpolatedData_o( ), | |
m_allData_o( ), | |
m_compare_f( f_compare_f ), | |
m_interpolate_f( f_interpolate_f ) | |
{ | |
// import input data | |
for( auto &data_o : *m_inputData_p ) | |
{ | |
m_allData_o.push_back( &data_o ); | |
} | |
} | |
~LazyInterpolation( ) | |
{ | |
// delete all intepolated data | |
for( auto *data_p : m_interpolatedData_o ) | |
{ | |
delete data_p; | |
} | |
} | |
/** | |
* @brief interpolate interpolates given value | |
* Searches for value in all interpolated data and returns it if | |
* available. Otherwise value will be interpolated by its nearest | |
* neighbours | |
* @param f_value_o value to be interpolated at | |
*/ | |
void interpolate( T &f_value_o ) | |
{ | |
int pos = findCrossOver( 0, m_allData_o.size()-1, &f_value_o ); | |
// desired value is smaller than every available value | |
if( pos == 0 && | |
m_compare_f( &f_value_o, m_allData_o.front() ) < 0) | |
{ | |
f_value_o = *m_allData_o.front(); | |
return; | |
} | |
// desired value is bigger than every available value | |
if( pos == m_allData_o.size()-1 && | |
m_compare_f( &f_value_o, m_allData_o.back() ) > 0) | |
{ | |
f_value_o = *m_allData_o.back(); | |
return; | |
} | |
// desired value is found | |
if( m_compare_f( &f_value_o, m_allData_o[pos] ) == 0) | |
{ | |
f_value_o = *m_allData_o[pos]; | |
return; | |
} | |
// interpolation needed | |
m_interpolate_f( m_allData_o[ pos ], m_allData_o[ pos + 1 ], f_value_o ); | |
m_interpolatedData_o.push_back( new T( f_value_o ) ); | |
m_allData_o.insert( pos + 1, m_interpolatedData_o.back( ) ); | |
} | |
/** | |
* @brief findCrossOver | |
* @param low | |
* @param high | |
* @param x | |
* @return position of nearest item (smaller/equal) in alldata to x | |
*/ | |
int findCrossOver( int low, int high, T *x ) | |
{ | |
// x is greater than all | |
if ( m_compare_f( m_allData_o[ high ], x ) >= 0 ) | |
{ | |
return high; | |
} | |
// x is smaller than all | |
if ( m_compare_f( m_allData_o[ low ], x ) <= 0 ) | |
{ | |
return low; | |
} | |
// Find the middle point | |
int mid = ( low + high ) / 2; | |
/* If x is same as middle element, then return mid */ | |
if ( m_compare_f( m_allData_o[ mid ], x ) >= 0 && | |
m_compare_f( m_allData_o[ mid + 1 ], x ) < 0 ) | |
{ | |
return mid; | |
} | |
if( m_compare_f( m_allData_o[ mid ], x ) > 0 ) | |
{ | |
return findCrossOver( mid+1, high, x ); | |
} | |
else | |
{ | |
return findCrossOver( low, mid - 1, x ); | |
} | |
} | |
private: | |
/// vector containing the given input data (needs to be sorted!) | |
Vector< T > *m_inputData_p = nullptr; | |
/// vector containing every interpolated data (unsorted) | |
Vector< T* > m_interpolatedData_o; | |
/// vector containing every data for searching (sorted) | |
Vector< T* > m_allData_o ; | |
/// function for comparison between to data T | |
/// Has to return -1 if left > right | |
/// 0 if left == right | |
/// 1 if left < right | |
std::function< int( T*, T* ) > m_compare_f; | |
/// function for interpolation between first two parameters | |
/// saves result in third parameter | |
std::function< void( T*, T*, T& ) > m_interpolate_f; | |
}; | |
#endif // LAZYINTERPOLATION_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment