seq_data.h

00001 
00005 #pragma once
00006 
00007 #include <usml/types/seq_vector.h>
00008 
00009 namespace usml {
00010 namespace types {
00011 
00012 using boost::numeric::ublas::vector;
00013 
00016 
00027 class USML_DECLSPEC seq_data : public seq_vector {
00028 
00029 protected:
00030 
00032     size_type _index;
00033 
00035     value_type _value;
00036 
00038     value_type _index_data;
00039 
00041     value_type _sign;
00042 
00043     //**************************************************
00044     // private functions
00045 
00054     void init( const double* data, size_t size ) {
00055         _data.resize(size) ;
00056         _increment.resize(size) ;
00057         _max_index = size-1;
00058         _index = 0;
00059         _value = data[0];
00060         _sign = 1.0;
00061         if (_max_index == 0) {
00062             _data[0] = data[0];
00063             _increment[0] = 0.0;
00064         } else if (_max_index > 0) {
00065 
00066             // process first element
00067 
00068             value_type left = data[1] - data[0];
00069             if (left < 0) {
00070                 _sign = -1.0;
00071             }
00072             _data[0] = data[0];
00073             _increment[0] = left;
00074 
00075             // process middle elements
00076 
00077             for ( size_type n = 1; n < _max_index; ++n ) {
00078                 value_type right = data[n+1] - data[n];
00079                 if (left * right <= 0) { // detect change of sign
00080                     throw std::invalid_argument("series not monotonic");
00081                 }
00082                 left = right;
00083                 _data[n] = data[n];
00084                 _increment[n] = left;
00085             }
00086 
00087             // process last element
00088 
00089             _data[ _max_index ] = data[ _max_index ];
00090             _increment[ _max_index ] = left;
00091         }
00092         _index_data = _data[_index] * _sign;
00093     }
00094 
00095     //**************************************************
00096     // virtual functions
00097 
00098 public:
00099 
00111     virtual size_type find_index(value_type value) {
00112 
00113         // Special case of data sets of size one
00114         if (_max_index == 0) {
00115             return 0;
00116         }
00117 
00118         // check for a redundant search
00119         if (value == _value) {
00120             return _index;
00121         }
00122         _value = value;
00123 
00124         // search backwards (toward the front)?
00125 
00126         value *= _sign;
00127         if (_index_data > value) {
00128 
00129             // Looping ends when the beginning of the list is hit or when
00130             // then new point is less than, or equal to, the search value.
00131 
00132             for (difference_type n = _index - 1; n >= 0 && _index_data > value; --n) {
00133                 _index_data = _data[--_index] * _sign;
00134             }
00135 
00136             // search forwards (toward the back)?
00137 
00138         } else if (_index_data < value) {
00139 
00140             // Looping ends when the end of the list is hit or when
00141             // new point is greater than, or equal to, the search value.
00142 
00143             difference_type N = size() - 2;
00144             for (difference_type n = _index + 1; n <= N && _index_data < value; ++n) {
00145                 _index_data = _data[++_index] * _sign;
00146             }
00147 
00148             // If new point is greater than the search value,
00149             // we've gone too far and we need to back up by one.
00150 
00151             if (_index_data > value && _index > 0) {
00152                 _index_data = _data[--_index] * _sign;
00153             }
00154 
00155         }
00156         return _index;
00157     }
00158 
00159     //***************************************************************
00160     // constructors and destructors
00161 
00163     virtual ~seq_data() {
00164     }
00165 
00171     seq_data(size_type size) : seq_vector(size) {
00172     }
00173 
00182     seq_data( const double* data, size_t size ) : seq_vector( size ) {
00183         init( data, size );
00184     }
00185 
00193     template<class T, class A> seq_data( const vector<T,A> &data ) :
00194             seq_vector( data.size() ) {
00195         const size_t N = data.size();
00196         double* buffer = new double[N];
00197         std::copy( data.begin(), data.end(), buffer );
00198         init( buffer, N );
00199         delete[] buffer ;
00200     }
00201 
00207     seq_data( const seq_data & copy ) :
00208         seq_vector(copy),
00209         _index(copy._index), _value(copy._value),
00210         _index_data(copy._index_data), _sign(copy._sign)
00211     {
00212     }
00213 
00215     virtual seq_vector* clone() const {
00216         return new seq_data(*this);
00217     }
00218 
00219 }; // end of class
00220 
00222 } // end of namespace types
00223 } // end of namespace usml

Generated on 4 May 2015 for USML by  doxygen 1.6.1