USML
seq_data.h
1 
5 #ifndef USML_TYPES_SEQ_DATA_H
6 #define USML_TYPES_SEQ_DATA_H
7 
8 #include <usml/types/seq_vector.h>
9 
10 namespace usml {
11 namespace types {
12 
13 using boost::numeric::ublas::vector;
14 
17 
28 class USML_DECLSPEC seq_data : public seq_vector {
29 
30  //**************************************************
31  // type definisions
32 
34 public:
35  typedef const vector_reference<const self_type> const_closure_type;
36  typedef vector_reference<self_type> closure_type;
37 
38 protected:
39 
41  size_type _index;
42 
45 
48 
51 
52  //**************************************************
53  // private functions
54 
61  void init( const double* data, unsigned size ) {
62  }
63 
64  //**************************************************
65  // virtual functions
66 
67 public:
68 
80  virtual size_type find_index(value_type value) {
81 
82  // check for a redundant search
83  if (_max_index == 0) {
84  return 0;
85  }
86 
87  if (value == _value) {
88  return _index;
89  }
90  _value = value;
91 
92  // search backwards (toward the front)?
93 
94  value *= _sign;
95  if (_index_data > value) {
96 
97  // Looping ends when the beginning of the list is hit or when
98  // then new point is less than, or equal to, the search value.
99 
100  for (difference_type n = _index - 1; n >= 0 && _index_data > value; --n) {
101  _index_data = _data(--_index) * _sign;
102  }
103 
104  // search forwards (toward the back)?
105 
106  } else if (_index_data < value) {
107 
108  // Looping ends when the end of the list is hit or when
109  // new point is greater than, or equal to, the search value.
110 
111  difference_type N = size() - 2;
112  for (difference_type n = _index + 1; n <= N && _index_data < value; ++n) {
113  _index_data = _data(++_index) * _sign;
114  }
115 
116  // If new point is greater than the search value,
117  // we've gone too far and we need to back up by one.
118 
119  if (_index_data > value && _index > 0) {
120  _index_data = _data(--_index) * _sign;
121  }
122 
123  }
124  return _index;
125  }
126 
127 
128  //***************************************************************
129  // constructors and destructors
130 
132  virtual ~seq_data() {
133  }
134 
140  seq_data(size_type size) : seq_vector(size) {
141  }
142 
151  seq_data( const double* data, unsigned size ) : seq_vector( size ) {
152  _index = 0 ;
153  _value = data[0] ;
154  _sign = 1.0;
155  _data[0] = _value;
156  if (_max_index > 0) {
157 
158  // process first element
159 
160  value_type left = data[1] - data[0] ;
161  if (left < 0) {
162  _sign = -1.0;
163  }
164  _increment[0] = left;
165 
166  // process middle elements
167 
168  for ( size_type n = 1; n < _max_index; ++n ) {
169  value_type right = data[n+1] - data[n] ;
170  if (left * right <= 0) { // detect change of sign
171  throw std::invalid_argument("series not monotonic");
172  }
173  left = right;
174  _data[n] = data[n];
175  _increment[n] = left;
176  }
177 
178  // process last element
179 
180  _data[ _max_index ] = data[ _max_index ];
181  _increment[ _max_index ] = left;
182  }
183  _index_data = _data[_index] * _sign;
184  }
185 
193  template<class T, class A> seq_data( const vector<T,A> &data )
194  : seq_vector( data.size() )
195  {
196  _index = 0 ;
197  _value = data[0] ;
198  _sign = 1.0;
199  if (_max_index > 0) {
200 
201  // process first element
202 
203  value_type left = data[1] - data[0] ;
204  if (left < 0) {
205  _sign = -1.0;
206  }
207  _data[0] = data[0] ;
208  _increment[0] = left;
209 
210  // process middle elements
211 
212  for ( size_type n = 1; n < _max_index; ++n ) {
213  value_type right = data[n+1] - data[n] ;
214  if (left * right <= 0) { // detect change of sign
215  throw std::invalid_argument("series not monotonic");
216  }
217  left = right;
218  _data[n] = data[n];
219  _increment[n] = left;
220  }
221 
222  // process last element
223 
224  _data[ _max_index ] = data[ _max_index ];
225  _increment[ _max_index ] = left;
226  }
227  _index_data = _data[_index] * _sign;
228  }
229 
235  seq_data( const seq_data & copy ) :
236  seq_vector(copy),
237  _index(copy._index), _value(copy._value),
238  _index_data(copy._index_data), _sign(copy._sign)
239  {
240  }
241 
243  virtual seq_vector* clone() const {
244  return new seq_data(*this);
245  }
246 
247 }; // end of class
248 
250 } // end of namespace types
251 } // end of namespace usml
252 
253 #endif
vector_reference< self_type > closure_type
Definition: seq_data.h:36
virtual ~seq_data()
Virtual destructor.
Definition: seq_data.h:132
size_type _index
index number from the last search
Definition: seq_data.h:41
seq_data(const seq_data &copy)
Copies data from another seq_data object.
Definition: seq_data.h:235
value_type _value
Value from the last search.
Definition: seq_data.h:44
seq_data(const vector< T, A > &data)
Construct sequence from a uBLAS vector.
Definition: seq_data.h:193
seq_data(const double *data, unsigned size)
Construct sequence from a standard C array.
Definition: seq_data.h:151
value_type _index_data
axis value that corresponds to _index
Definition: seq_data.h:47
const vector_reference< const self_type > const_closure_type
Definition: seq_data.h:35
Sequence defined by an unevenly spaced vector of points.
Definition: seq_data.h:28
seq_data self_type
Definition: seq_data.h:33
virtual size_type find_index(value_type value)
Search for a value in this sequence.
Definition: seq_data.h:80
value_type _sign
Sign value is 1 if the sequence is increasing, -1 if decreasing.
Definition: seq_data.h:50
vector< value_type >::difference_type difference_type
Definition: seq_vector.h:45
virtual seq_vector * clone() const
Create a copy using a reference to the base class.
Definition: seq_data.h:243
A read-only, monotonic sequence of values.
Definition: seq_vector.h:36
void init(const double *data, unsigned size)
Definition: seq_data.h:61
double value_type
Definition: seq_vector.h:43
seq_data(size_type size)
Initialize sequence sub-class using number of elements.
Definition: seq_data.h:140